mirror of
https://github.com/zeromq/libzmq.git
synced 2025-10-22 16:02:31 +02:00
Problem: can't unbind with bound addr with IPv6
Solution: try to resolve the TCP endpoint passed by the user in the zmq_unbind call before giving up, if it doesn't match. This fixes a breakage in the API, where after a call to zmq_bind(s, "tcp://127.0.0.1:9999") with IPv6 enabled on s would result in the call to zmq_unbind(s, "tcp://127.0.0.1:9999") failing. Add more test cases to increase coverage on all combinations of TCP endpoints.
This commit is contained in:
@@ -1029,8 +1029,38 @@ int zmq::socket_base_t::term_endpoint (const char *addr_)
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string resolved_addr = std::string (addr_);
|
||||
std::pair <endpoints_t::iterator, endpoints_t::iterator> range;
|
||||
|
||||
// The resolved last_endpoint is used as a key in the endpoints map.
|
||||
// The address passed by the user might not match in the TCP case due to
|
||||
// IPv4-in-IPv6 mapping (EG: tcp://[::ffff:127.0.0.1]:9999), so try to
|
||||
// resolve before giving up. Given at this stage we don't know whether a
|
||||
// socket is connected or bound, try with both.
|
||||
if (protocol == "tcp") {
|
||||
range = endpoints.equal_range (resolved_addr);
|
||||
if (range.first == range.second) {
|
||||
tcp_address_t *tcp_addr = new (std::nothrow) tcp_address_t ();
|
||||
alloc_assert (tcp_addr);
|
||||
rc = tcp_addr->resolve (address.c_str (), false, options.ipv6);
|
||||
|
||||
if (rc == 0) {
|
||||
tcp_addr->to_string (resolved_addr);
|
||||
range = endpoints.equal_range (resolved_addr);
|
||||
|
||||
if (range.first == range.second) {
|
||||
rc = tcp_addr->resolve (address.c_str (), true, options.ipv6);
|
||||
if (rc == 0) {
|
||||
tcp_addr->to_string (resolved_addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
LIBZMQ_DELETE(tcp_addr);
|
||||
}
|
||||
}
|
||||
|
||||
// Find the endpoints range (if any) corresponding to the addr_ string.
|
||||
std::pair <endpoints_t::iterator, endpoints_t::iterator> range = endpoints.equal_range (std::string (addr_));
|
||||
range = endpoints.equal_range (resolved_addr);
|
||||
if (range.first == range.second) {
|
||||
errno = ENOENT;
|
||||
EXIT_MUTEX ();
|
||||
|
Reference in New Issue
Block a user