Skip to content
This repository has been archived by the owner on Nov 28, 2020. It is now read-only.

how to bind to a IPv4 socket #137

Open
jeremyandrews opened this issue May 10, 2020 · 5 comments
Open

how to bind to a IPv4 socket #137

jeremyandrews opened this issue May 10, 2020 · 5 comments
Labels
question Further information is requested

Comments

@jeremyandrews
Copy link

All attempts to bind to an address are creating an IPv6 socket instead of the desired IPv4 socket.

For example:

    let addr: TcpAddr = "0.0.0.0:1234".try_into().unwrap();
    let server = ServerBuilder::new().bind(&addr).build().unwrap();
    let bound = server.last_endpoint().unwrap();
    println!("{:?}", bound);

Results in the following output:

Tcp(TcpAddr { src: None, host: SocketAddr { interface: Ip(V6(::ffff:0.0.0.0)), port: Specified(1234) } })

Using my actual IP address instead of 0.0.0.0 has the same general problem:

Tcp(TcpAddr { src: None, host: SocketAddr { interface: Ip(V6(::ffff:10.10.200.150)), port: Specified(1234) } })

I saw some examples that specify the interface, for example:

    let addr: TcpAddr = "wlp0s20f3;10.10.200.150:1234".try_into().unwrap();
    let server = ServerBuilder::new().bind(&addr).build().unwrap();

But this results in a panic:

thread 'main' panicked at 'invalid endpoint : tcp://10.10.200.150:1234;wlp0s20f3', .cargo/registry/src/github.com-1ecc6299db9ec823/libzmq-0.2.4/src/core/raw.rs:93:17

The backtrace:

  12: std::panicking::begin_panic_fmt
             at src/libstd/panicking.rs:332
  13: libzmq::core::raw::bind
             at src/github.com-1ecc6299db9ec823/libzmq-0.2.4/src/core/raw.rs:93
  14: libzmq::core::raw::RawSocket::bind
             at src/github.com-1ecc6299db9ec823/libzmq-0.2.4/src/core/raw.rs:233
  15: libzmq::core::Socket::bind
             at src/github.com-1ecc6299db9ec823/libzmq-0.2.4/src/core/mod.rs:283
  16: libzmq::core::SocketConfig::apply
             at src/github.com-1ecc6299db9ec823/libzmq-0.2.4/src/core/mod.rs:570
  17: libzmq::socket::server::ServerConfig::apply
             at src/github.com-1ecc6299db9ec823/libzmq-0.2.4/src/socket/server.rs:206
  18: libzmq::socket::server::ServerConfig::with_ctx
             at src/github.com-1ecc6299db9ec823/libzmq-0.2.4/src/socket/server.rs:197
  19: libzmq::socket::server::ServerConfig::build
             at src/github.com-1ecc6299db9ec823/libzmq-0.2.4/src/socket/server.rs:192
  20: libzmq::socket::server::ServerBuilder::build
             at src/github.com-1ecc6299db9ec823/libzmq-0.2.4/src/socket/server.rs:335

I assume I'm doing something wrong, any help would be greatly appreciated.

If helpful, the actual code where I'm trying to implement this can be viewed here:
https://github.com/jeremyandrews/goose/blob/gaggle/src/manager.rs

And I'm running with the following command:

cargo run --example simple -- --manager --manager-bind-host "wlp0s20f3;10.10.200.150" --manager-bind-port 1234 --expect-workers 3 --host http://apache.fosciana/ -vv

I'm compiling on Linux in an Ubuntu-based distribution (PopOS). Here's my interfaces:

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: wlp0s20f3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 28:7f:cf:74:1d:23 brd ff:ff:ff:ff:ff:ff
    inet 10.10.200.150/16 brd 10.10.255.255 scope global dynamic noprefixroute wlp0s20f3
       valid_lft 6743sec preferred_lft 6743sec
    inet6 fe80::1c3d:22e5:738d:2989/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
@jeremyandrews jeremyandrews added the question Further information is requested label May 10, 2020
@jeremyandrews
Copy link
Author

jeremyandrews commented May 10, 2020

And netstat showing that indeed it's incorrectly creating an IPv6 socket:

$ netstat -an | grep 1234
tcp6       0      0 127.0.0.1:1234          :::*                    LISTEN     

@jean-airoldie
Copy link
Owner

Currently its not supported, but it should be straight forward to add, a PR would be most welcomed.

By default the context enables the IPv6 features which probably forces a v6 socket to be created even with a v4 address. So I'm assuming allowing the user to modify the following line would work:

inner.set_bool(CtxOption::IPV6, true).unwrap();

I think the best approach would be to add a new force_ipv4 (or a better name) method to the CtxBuilder to toggle this option.

@jean-airoldie
Copy link
Owner

Yeah pretty sure this would work, after reading the zmq API doc:

The ZMQ_IPV6 argument sets the IPv6 value for all sockets created in the context from this point onwards. A value of 1 means IPv6 is enabled, while 0 means the socket will use only IPv4. When IPv6 is enabled, a socket will connect to, or accept connections from, both IPv4 and IPv6 hosts.

(Taken from http://api.zeromq.org/master:zmq-ctx-set)

@jeremyandrews
Copy link
Author

Ah, I see. So it is creating an IPv4 socket, it's just creating an IPv6 socket as well.

It seems my problem is different than I thought, then -- recv_msg() isn't returning anything even when a client connects to the socket (or I telnet to the socket), and thus hanging forever.

@jean-airoldie
Copy link
Owner

It seems my problem is different than I thought, then -- recv_msg() isn't returning anything even when a client connects to the socket (or I telnet to the socket), and thus hanging forever.

The Server does not receive a notification when a new client gets connected, only when it sends a new message.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants