Skip to content

Conversation

yashksaini-coder
Copy link
Contributor

What was wrong?

My previous PR #811 lacked the code changes on, multiple examples and core modules that were using wildcard addresses (0.0.0.0) for binding, which could expose services on all network interfaces and create security vulnerabilities.

How was it fixed?

I updated all the modules files and refactored to replace all wildcard bind addresses (0.0.0.0) with secure loopback addresses (127.0.0.1) across the entire codebase:

Examples Directory (17 files updated)

  • Core examples: ping.py, chat.py, bootstrap.py, mDNS.py, pubsub.py, random_walk.py, identify.py, identify_push_listener_dialer.py
  • Documentation examples: All 8 files in examples/doc-examples/ directory
  • Advanced examples: network_discover.py (updated fallback functions)

Core Library Updates

  • libp2p/utils/address_validation.py: Updated fallback addresses from 0.0.0.0 to 127.0.0.1

Documentation Updates (5 files)

  • Updated all .rst files in docs/examples.*.rst to reflect new secure addresses

Testing & Validation

  • tests/utils/test_default_bind_address.py: Comprehensive tests for secure address selection
  • tests/examples/test_examples_bind_address.py: Validation that all examples use secure addresses

Release Notes

  • newsfragments/885.feature.rst: Security enhancement notification

To-Do

  • Clean up commit history
  • Add or update documentation related to these changes
  • Add entry to the release notes

cc: @acul71 @seetadev @pacrob

@seetadev
Copy link
Contributor

seetadev commented Sep 2, 2025

@yashksaini-coder : Great contribution, Yash. Appreciate your efforts. This PR is coming along nicely.

Looking forward to detailed review by @acul71 on this PR.

@acul71
Copy link
Contributor

acul71 commented Sep 2, 2025

@yashksaini-coder

  1. Fix the get_available_interfaces so that it don't return duplicate addresses
  2. Take a look at all the examples in /examples and when you see something like that:
(venv) luca@r17:~/PNL_Launchpad_Curriculum/Libp2p/py-libp2p$ identify-demo 
First host listening (using raw protobuf format). Run this from another console:

identify-demo --raw-format -d /ip4/127.0.0.1/tcp/37511/p2p/QmVUKiaLFMt9AVALFTPCRycCM2FArzugTLScVKaeeoCyxc

or like that

(venv) luca@r17:~/PNL_Launchpad_Curriculum/Libp2p/py-libp2p$ ping-demo 
Run this from the same folder in another console:

ping-demo -d /ip4/0.0.0.0/tcp/42547/p2p/QmRShbR5CqVSkF4zWKCUhx7BwU9MonXV5LNxFDT1CborEk

Waiting for incoming connection...

it should be instead similar to this:

(venv) luca@r17:~/PNL_Launchpad_Curriculum/Libp2p/py-libp2p$ echo-demo 
Listener ready, listening on:

/ip4/192.168.1.17/tcp/43857/p2p/16Uiu2HAmJcvmEow2iaFDEexsN2HMqzX8DcwxhDct87YYnoQNhv7m
/ip4/10.156.233.51/tcp/43857/p2p/16Uiu2HAmJcvmEow2iaFDEexsN2HMqzX8DcwxhDct87YYnoQNhv7m
/ip4/127.0.0.1/tcp/43857/p2p/16Uiu2HAmJcvmEow2iaFDEexsN2HMqzX8DcwxhDct87YYnoQNhv7m

Run this from the same folder in another console:

echo-demo -d /ip4/192.168.1.17/tcp/43857/p2p/16Uiu2HAmJcvmEow2iaFDEexsN2HMqzX8DcwxhDct87YYnoQNhv7m

Waiting for incoming connections...

So that it shows all available interfaces and a default command for the client (Run this form the same folder in ......)

  1. Test manually all the tests (not all options) to see that they work with your mods (there are some tests but don't cover a real test)
    This way you also become familiar with various core protocols in py-libp2p

@yashksaini-coder yashksaini-coder changed the title Fix/885 update default bind address WIP Fix/885 update default bind address Sep 5, 2025
@yashksaini-coder
Copy link
Contributor Author

yashksaini-coder commented Sep 5, 2025

@seetadev @sumanjeet0012 Hi, I've worked and improved this PR with updated function get_all_interfaces, I was going to tag Luca, but he is facing problem with his Github account.

I need assistance, since the checks are going failed. Seems that the py-cid repo is not able to clone

Please take a look, I've run all checks locally, pre-commit, make pr, make fix

@sumanjeet0012
Copy link
Contributor

@yashksaini-coder The GitHub account of Luca is currently suspended, which is causing this issue.
Could you please share the results of the checks and tests you ran locally?

@yashksaini-coder
Copy link
Contributor Author

@yashksaini-coder The GitHub account of Luca is currently suspended, which is causing this issue. Could you please share the results of the checks and tests you ran locally?

yes I got the message yesterday, I have got the extended review and follow up steps on this PR, I will update you later. currently occupied on job work.

Thanks

yashksaini-coder and others added 3 commits September 6, 2025 23:41
…rd support

- Introduced `get_wildcard_address` function for explicit wildcard binding.
- Updated examples to use `get_available_interfaces` and `get_optimal_binding_address` for address selection.
- Ensured consistent usage of the new address paradigm across all example files.
- Added tests to verify the implementation of the new address paradigm and wildcard feature.
@acul71
Copy link
Contributor

acul71 commented Sep 9, 2025

@yashksaini-coder @seetadev
Test message

@acul71
Copy link
Contributor

acul71 commented Sep 9, 2025

@yashksaini-coder Does it need to be reviewed ?

@seetadev
Copy link
Contributor

seetadev commented Sep 9, 2025

@sumanjeet0012 , @acul71 : Lets do a detailed review on it.

@yashksaini-coder
Copy link
Contributor Author

@yashksaini-coder Does it need to be reviewed ?

yes

@yashksaini-coder yashksaini-coder changed the title WIP Fix/885 update default bind address Fix/885 update default bind address Sep 11, 2025
@acul71
Copy link
Contributor

acul71 commented Sep 15, 2025

@yashksaini-coder

Code Review: Address Paradigm Implementation (PR #885)

The implementation successfully introduces the new address paradigm with get_available_interfaces() and get_optimal_binding_address() functions. However, there are 2 critical issues where 0.0.0.0 (all interfaces) was incorrectly changed to 127.0.0.1 (localhost only), breaking network accessibility in QUIC examples.

✅ Good Changes

  • New paradigm functions: Properly implemented get_available_interfaces() and get_optimal_binding_address()
  • Wildcard support: Added get_wildcard_address() for explicit wildcard binding when needed
  • Most examples updated: Correctly migrated to use the new paradigm
  • Test coverage: Updated tests to validate the new approach
  • Documentation examples: Most doc examples properly use the new functions

❌ Critical Issues

Issue 1: Mass Conversion of 0.0.0.0 to 127.0.0.1 (Commit 8755011)

Problem: Changed 0.0.0.0 to 127.0.0.1 in 18 files across all examples
Files affected:

  • examples/doc-examples/example_encryption_insecure.py
  • examples/doc-examples/example_encryption_noise.py
  • examples/doc-examples/example_encryption_secio.py
  • examples/doc-examples/example_multiplexer.py
  • examples/doc-examples/example_net_stream.py
  • examples/doc-examples/example_peer_discovery.py
  • examples/doc-examples/example_running.py
  • examples/doc-examples/example_transport.py
  • examples/identify/identify.py
  • examples/identify_push/identify_push_listener_dialer.py
  • examples/mDNS/mDNS.py
  • examples/ping/ping.py
  • examples/pubsub/pubsub.py
  • examples/random_walk/random_walk.py
  • examples/bootstrap/bootstrap.py
  • examples/chat/chat.py
  • examples/advanced/network_discover.py
  • libp2p/utils/address_validation.py

Impact: All examples became localhost-only, breaking network accessibility

Issue 2: Incomplete Fix in Latest Commit

Problem: Only partially implemented the new paradigm, leaving many files still broken
Still broken:

  • examples/doc-examples/example_quic_transport.py (line 24)
  • examples/echo/echo_quic.py (line 52)
  • All the encryption examples still use hardcoded 127.0.0.1
  • All the other doc examples still use hardcoded 127.0.0.1

🔧 Recommended Fixes

Option 1: Use New Paradigm (Recommended)

# Replace hardcoded addresses with:
listen_addrs = get_available_interfaces(port)
# Then use: async with host.run(listen_addrs=listen_addrs)

Option 2: Keep Wildcard for Demos

# If examples need to be accessible from other machines:
listen_addr = multiaddr.Multiaddr(f"/ip4/0.0.0.0/udp/{port}/quic-v1")

Conclusion

The implementation has two major problems:

  1. First commit: Mass conversion of 0.0.0.0 to 127.0.0.1 broke all examples
  2. Second commit: Incomplete fix that only addressed some files

The entire examples directory needs to be systematically updated to use the new address paradigm functions instead of hardcoded 127.0.0.1 addresses.

Status: ❌ Major fixes required before merge

@yashksaini-coder
Copy link
Contributor Author

@acul71 glad to see you are back, I'm working on the interops testing of python and js, so the branch didn't update there was a third commit that handle update to all the files, I will commit after checking and updating branch, thanks for detailed analysis.

@acul71
Copy link
Contributor

acul71 commented Sep 18, 2025

@yashksaini-coder

I can see that in identify-demo the wrong parameter is showed at screen: the default is without --raw-format

identify-demo --raw-format -d /ip4/192.168.1.232/tcp/46067/p2p/QmVorJGQfjEA3bJh6k4EaiQd2wPWYM82BT5ttqFg2YvTAB

(venv) luca@r17:~/PNL_Launchpad_Curriculum/Libp2p/py-libp2p$ identify-demo 
2025-09-17 19:56:15,126 [DEBUG] [async_service.Manager] <Manager[Swarm] flags=SRcfe>: _handle_cancelled waiting for cancellation
First host listening (using raw protobuf format).
Listener ready, listening on:

/ip4/192.168.1.232/tcp/46067/p2p/QmVorJGQfjEA3bJh6k4EaiQd2wPWYM82BT5ttqFg2YvTAB
/ip4/10.156.233.51/tcp/46067/p2p/QmVorJGQfjEA3bJh6k4EaiQd2wPWYM82BT5ttqFg2YvTAB
/ip4/127.0.0.1/tcp/46067/p2p/QmVorJGQfjEA3bJh6k4EaiQd2wPWYM82BT5ttqFg2YvTAB

Run this from the same folder in another console:

identify-demo --raw-format -d /ip4/192.168.1.232/tcp/46067/p2p/QmVorJGQfjEA3bJh6k4EaiQd2wPWYM82BT5ttqFg2YvTAB

@acul71
Copy link
Contributor

acul71 commented Sep 18, 2025

@yashksaini-coder

Code Review: Address Paradigm Implementation (PR #885) - Follow-up

MAJOR IMPROVEMENTS - Issues Successfully Addressed

The developer yashksaini-coder has successfully addressed ALL critical issues identified in the previous review. The implementation now properly uses the new address paradigm throughout the codebase.

Fixed Issues

Issue 1: QUIC Examples Fixed ✅

Previously broken files now properly implemented:

  • examples/doc-examples/example_quic_transport.py - Now uses get_available_interfaces() and get_optimal_binding_address()
  • examples/echo/echo_quic.py - Completely rewritten with proper address paradigm usage

Issue 2: All Encryption Examples Fixed ✅

All encryption examples now use the new paradigm:

  • examples/doc-examples/example_encryption_insecure.py - Uses get_available_interfaces() and get_optimal_binding_address()
  • examples/doc-examples/example_encryption_noise.py - Uses get_available_interfaces() and get_optimal_binding_address()
  • examples/doc-examples/example_encryption_secio.py - Uses get_available_interfaces() and get_optimal_binding_address()

Issue 3: All Other Examples Fixed ✅

All remaining examples properly updated:

  • examples/doc-examples/example_multiplexer.py - Uses new paradigm
  • examples/doc-examples/example_net_stream.py - Uses new paradigm
  • examples/identify/identify.py - Uses new paradigm
  • examples/ping/ping.py - Uses new paradigm
  • examples/pubsub/pubsub.py - Uses new paradigm
  • examples/bootstrap/bootstrap.py - Uses new paradigm
  • examples/chat/chat.py - Uses new paradigm

Implementation Quality

Consistent Pattern Usage

All examples now follow the recommended pattern:

# Get available interfaces
listen_addrs = get_available_interfaces(port)
# Get optimal address for client commands
optimal_addr = get_optimal_binding_address(port)
# Use in host.run()
async with host.run(listen_addrs=listen_addrs):

QUIC-Specific Handling

QUIC examples properly handle protocol conversion:

# Convert TCP addresses to QUIC addresses
quic_addrs = []
for addr in listen_addrs:
    addr_str = str(addr).replace("/tcp/", "/udp/") + "/quic-v1"
    quic_addrs.append(Multiaddr(addr_str))

Address Validation Module

The libp2p/utils/address_validation.py module is properly implemented with:

  • get_available_interfaces() - Discovers all available network interfaces
  • get_optimal_binding_address() - Chooses optimal binding address
  • get_wildcard_address() - Provides explicit wildcard binding when needed
  • Proper IPv4/IPv6 handling with fallbacks

Network Accessibility Restored

  • No more hardcoded 127.0.0.1 - All examples now bind to all available interfaces
  • Network accessibility restored - Examples can now be accessed from other machines
  • Proper fallback handling - Graceful degradation when interfaces are unavailable

Code Quality Improvements

  • Consistent imports - All examples import the new address validation functions
  • Proper error handling - Examples handle port allocation and interface discovery
  • Clear documentation - Examples show optimal addresses for client connections
  • Protocol flexibility - Support for both TCP and UDP protocols

Critical Bug Found in identify-demo

Issue: Inverted Format Logic

Problem: The identify-demo shows incorrect command line instructions to users.

Current behavior:

  • When running without --raw-format (default), it shows "using raw protobuf format" but tells users to run with --raw-format
  • When running with --raw-format, it shows "using length-prefixed format" but tells users to run without --raw-format

Root cause: Line 289 in examples/identify/identify.py:

# WRONG: This inverts the logic
use_varint_format = args.raw_format

Should be:

# CORRECT: --raw-format means NOT using varint format
use_varint_format = not args.raw_format

Evidence from testing:

First host listening (using raw protobuf format).  # ← Says "raw protobuf"
# But then shows:
identify-demo --raw-format -d ...  # ← Tells user to use --raw-format

🔧 Required Fix

Fix the format logic in examples/identify/identify.py:

# Line 289 - CHANGE FROM:
use_varint_format = args.raw_format

# TO:
use_varint_format = not args.raw_format

Explanation:

  • --raw-format flag means "use raw protobuf format" (old format)
  • use_varint_format = True means "use length-prefixed format" (new format)
  • So when --raw-format is True, use_varint_format should be False

🧪 Comprehensive Testing Requirements

To ensure all examples work correctly, yashksaini-coder must provide evidence of manual testing for each example:

Required Testing Evidence

For each example, provide ONE of the following:

  1. Screenshots showing:

    • Server starting successfully
    • Client connecting successfully
    • Data exchange working
    • Both processes running simultaneously
  2. Terminal output logs showing:

    • Complete server startup sequence
    • Client connection and data exchange
    • No errors or exceptions
  3. Short video recordings (30-60 seconds) showing:

    • Server startup
    • Client connection
    • Data exchange
    • Both terminals visible

Examples to Test

Basic Examples (Must work)

  1. echo-demo - python examples/echo/echo.py -p 8000 + client
  2. ping-demo - python examples/ping/ping.py -p 8001 + client
  3. chat-demo - python examples/chat/chat.py -p 8002 + client
  4. identify-demo - python examples/identify/identify.py -p 8003 + client (after fix)

QUIC Examples (Must work)

  1. echo-quic-demo - python examples/echo/echo_quic.py -p 8004 + client
  2. quic-transport-demo - python examples/doc-examples/example_quic_transport.py

Encryption Examples (Must work)

  1. insecure-encryption - python examples/doc-examples/example_encryption_insecure.py
  2. noise-encryption - python examples/doc-examples/example_encryption_noise.py
  3. secio-encryption - python examples/doc-examples/example_encryption_secio.py

Advanced Examples (Must work)

  1. pubsub-demo - python examples/pubsub/pubsub.py -p 8005 + client
  2. bootstrap-demo - python examples/bootstrap/bootstrap.py -p 8006
  3. net-stream-demo - python examples/doc-examples/example_net_stream.py -p 8007 + client

Testing Protocol

For each example:

  1. Start server in one terminal
  2. Verify server shows correct addresses (not just 127.0.0.1)
  3. Start client in another terminal using the provided command
  4. Verify connection succeeds
  5. Verify data exchange works
  6. Take screenshot/video of both terminals

Success Criteria

Server starts without errors
Server binds to multiple interfaces (not just localhost)
Client connects successfully
Data exchange works
No hardcoded 127.0.0.1 addresses in output
identify-demo shows correct command format

📋 Deliverables Required

yashksaini-coder must provide:

  1. Fix the identify-demo format logic bug
  2. Testing evidence for ALL 12 examples (screenshots, logs, or videos)
  3. (OPTIONAL) Confirmation that all examples work from different machines (network accessibility)
  4. Documentation of any issues found during testing

🎯 Summary

Status: ❌ BLOCKED - Critical bug + testing required

The developer has successfully:

  1. ✅ Fixed all QUIC examples to use the new address paradigm
  2. ✅ Updated all encryption examples to use the new paradigm
  3. ✅ Migrated all remaining examples to the new paradigm
  4. ✅ Restored network accessibility across all examples
  5. ✅ Maintained consistent code quality and patterns

However, a critical bug was found in identify-demo that must be fixed, and comprehensive manual testing is required before final approval.

Next Steps:

  1. Fix identify-demo format logic
  2. Run comprehensive manual testing
  3. Provide evidence of all examples working
  4. Confirm network accessibility

Only after completing all testing with evidence will this PR be ready for final approval.

@yashksaini-coder
Copy link
Contributor Author

@yashksaini-coder

I can see that in identify-demo the wrong parameter is showed at screen: the default is without --raw-format

identify-demo --raw-format -d /ip4/192.168.1.232/tcp/46067/p2p/QmVorJGQfjEA3bJh6k4EaiQd2wPWYM82BT5ttqFg2YvTAB

(venv) luca@r17:~/PNL_Launchpad_Curriculum/Libp2p/py-libp2p$ identify-demo 
2025-09-17 19:56:15,126 [DEBUG] [async_service.Manager] <Manager[Swarm] flags=SRcfe>: _handle_cancelled waiting for cancellation
First host listening (using raw protobuf format).
Listener ready, listening on:

/ip4/192.168.1.232/tcp/46067/p2p/QmVorJGQfjEA3bJh6k4EaiQd2wPWYM82BT5ttqFg2YvTAB
/ip4/10.156.233.51/tcp/46067/p2p/QmVorJGQfjEA3bJh6k4EaiQd2wPWYM82BT5ttqFg2YvTAB
/ip4/127.0.0.1/tcp/46067/p2p/QmVorJGQfjEA3bJh6k4EaiQd2wPWYM82BT5ttqFg2YvTAB

Run this from the same folder in another console:

identify-demo --raw-format -d /ip4/192.168.1.232/tcp/46067/p2p/QmVorJGQfjEA3bJh6k4EaiQd2wPWYM82BT5ttqFg2YvTAB

@acul71 okh changed the default param during identify-demo

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants