- if (1) {
- int port;
- int one = 1;
-
- setsockopt(rpc->fd, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one));
-
- for (port = 200; port < 500; port++) {
- struct sockaddr_in sin;
-
- memset(&sin, 0, sizeof(sin));
- sin.sin_port = htons(port);
- sin.sin_family = AF_INET;
- sin.sin_addr.s_addr = 0;
+ {
+ struct sockaddr_storage ss;
+ static int portOfs = 0;
+ const int firstPort = 512; /* >= 512 according to Sun docs */
+ const int portCount = IPPORT_RESERVED - firstPort;
+ int startOfs, port, rc;
+
+ if (portOfs == 0) {
+ portOfs = time(NULL) % 400;
+ }
+ startOfs = portOfs;
+ do {
+ rc = -1;
+ port = htons(firstPort + portOfs);
+ portOfs = (portOfs + 1) % portCount;
+
+ /* skip well-known ports */
+ if (!getservbyport(port, "tcp")) {
+ memset(&ss, 0, sizeof(ss));
+
+ switch (s->ss_family) {
+ case AF_INET:
+ ((struct sockaddr_in *)&ss)->sin_port = port;
+ ((struct sockaddr_in *)&ss)->sin_family = AF_INET;
+#ifdef HAVE_SOCKADDR_LEN
+ ((struct sockaddr_in *)&ss)->sin_len = sizeof(struct sockaddr_in);
+#endif
+ break;
+ case AF_INET6:
+ ((struct sockaddr_in6 *)&ss)->sin6_port = port;
+ ((struct sockaddr_in6 *)&ss)->sin6_family = AF_INET6;
+#ifdef HAVE_SOCKADDR_LEN
+ ((struct sockaddr_in6 *)&ss)->sin6_len = sizeof(struct sockaddr_in);
+#endif
+ break;
+ }