-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 16/11/14 05:45, Matt Howlett wrote: > It should be treated as a failure to connect. The implementation > should try to re-connect assuming that the interface will become > available eventually. > > > I think it would be very common for people to want an atomic way > of checking if a port is free, binding to it if it is, and moving > on if it is not (I want this and I notice a number of others here > do too). I also think that in most scenarios where a port is > already in use, it's likely to stay that way for a time period long > enough that the application wanting to bind to it is not going to > find it useful to wait for it to become free (I'm not an expert > though and could be missing a common scenario where this > functionality is actually useful - examples?). So based on that, I > think the former behavior is the best, or should at least be an > option. Ok, let me give you the big picture. Long ago the authors of Internet protocol suite have decided to use 16-bit integer IDs to address different "services" on a host. I guess back then the decision must have seemed reasonable, but later on it became clear that the namespace is too small and the service often clash using the same ID (port). In 1988 there was an attempt to solve the problem (at least for TCP) by defining a protocol that used arbitrary string as IDs instead of integers (TCPMUX, RFC 1078, TCP port 1) but it never got wide adoption. If you think of it, using strings solves the problem fully. You can use fully qualified name as a service ID, it can contain the name of the vendor etc. In such world there's would be no service name clashes and thus no need for dynamically assigned service IDs. Unfortunately, TCPMUX was ignored and instead everybody sticks to port numbers and hacks around the problem using dynamically assigned ports. Yet, dynamically assigned IDs are a spectacularly bad solution: 1. The dynamically assigned ID has to be somehow communicated to the peers in runtime. That adds whole new layer of complexity to the applications. 2. Given that service IDs change as the services are restarted, there's no way to define service-specific policies at network level (e.g. allocating 100MB/s of bandwidth for service X). 3. The solution is prone to inconsistencies and race conditions, with different nodes having different ideas about what the ID of service X happens to be. You can think of it as a very simple distributed database which means you have to deal with CAP theorem: Either you can always determine the port number to use (Availability) or everybody can agree on the same number (Consistency) -- bet never both. In context of nanomsg (which does automatics reconnecting) the problem becomes even more pronounced: Say you bind to a wi-fi interface, get port X assigned, then the interface goes away (you are out of range of the wi-fi), then becomes available once more. You can try to re-bind to the same port, but it may already be taken. You can ask for a new dynamically allocated port but then it's certainly going to be different from the old one. The change would have to be communicated back to the application. How? Callback? And even if so, what would application do in such case? Et c. The bottom line is the we should rather than using dynamically assigned ports we should rather using string-based service names. I was thinking of actually implementing TCPMUX, but the idea surfaced again yesterday when speaking of WebSocket transport and using WebSocket URLs basically as service names. Well, that's more or less it. Sorry for the long rant but I hope it'll explain why things are done as they are and what is my preferred solution to the problem of service ID clashes. Martin -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQEcBAEBAgAGBQJUaLIPAAoJENTpVjxCNN9YIfoH/R38pX4NqwoxafShyYzzgiXQ BSkMgF/lRpWD1MZwkJxPLG0lfbIiZioGNn0Zhy3fEyEkxqkSfbS12IvOrJ02XmYH cg4WPFAOIu9EKfgJdUC3OQaa7vXVdB+M5QEEAWInCPffNGUTudmd3GXYsfix6ml6 7HBpDnV0e8cpGie6xpRPsWNxl7k/6o7a5hEHhgqdZDeI2w1NjON7J2VN1eH8mkBP +Y4vsXeOgHIKpGd5XXmC+65KV82sZkzxMeTkeGDa/F08VpAdDA84htHeW/VcZZCi TDZ7+YROKoWECAmC3XDRMVtpXMUYHZWFJVivULigxyQLPmJkW1mPtKzaKVjEkow= =mcjQ -----END PGP SIGNATURE-----