static int32_t af_inet_bind_to_port_lt_ceiling(int fd, struct sockaddr *sockaddr, socklen_t sockaddr_len, uint32_t ceiling) { #if GF_DISABLE_PRIVPORT_TRACKING _assign_port(sockaddr, 0); return bind(fd, sockaddr, sockaddr_len); #else int32_t ret = -1; uint16_t port = ceiling - 1; unsigned char ports[GF_PORT_ARRAY_SIZE] = { 0, }; int i = 0; loop: ret = gf_process_reserved_ports(ports, ceiling); while (port) { if (port == GF_CLIENT_PORT_CEILING) { ret = -1; break; } /* ignore the reserved ports */ if (BIT_VALUE(ports, port)) { port--; continue; } _assign_port(sockaddr, port); ret = bind(fd, sockaddr, sockaddr_len); if (ret == 0) break; if (ret == -1 && errno == EACCES) break; port--; } /* In case if all the secure ports are exhausted, we are no more * binding to secure ports, hence instead of getting a random * port, lets define the range to restrict it from getting from * ports reserved for bricks i.e from range of 49152 - 65535 * which further may lead to port clash */ if (!port) { ceiling = port = GF_CLNT_INSECURE_PORT_CEILING; for (i = 0; i <= ceiling; i++) BIT_CLEAR(ports, i); goto loop; } return ret; #endif /* GF_DISABLE_PRIVPORT_TRACKING */ }
static int32_t af_inet_bind_to_port_lt_ceiling (int fd, struct sockaddr *sockaddr, socklen_t sockaddr_len, uint32_t ceiling) { int32_t ret = -1; uint16_t port = ceiling - 1; // by default assume none of the ports are blocked and all are available gf_boolean_t ports[GF_PORT_MAX] = {_gf_false,}; int i = 0; ret = gf_process_reserved_ports (ports, ceiling); if (ret != 0) { for (i = 0; i < GF_PORT_MAX; i++) ports[i] = _gf_false; } while (port) { // ignore the reserved ports if (ports[port] == _gf_true) { port--; continue; } _assign_port (sockaddr, port); ret = bind (fd, sockaddr, sockaddr_len); if (ret == 0) break; if (ret == -1 && errno == EACCES) break; port--; } return ret; }