fr_assert((my->info.socket.af == AF_INET) || (my->info.socket.af == AF_INET6));
+ /*
+ * Ranges must be a high value.
+ */
+ if (my->info.cfg->src_port_start && (my->info.cfg->src_port_start < 1024)) {
+ fr_strerror_const("Cannot set src_port_start in the range 1..1023");
+ return -1;
+ }
+
#ifdef HAVE_CAPABILITY_H
/*
- * If we're binding to a special port as non-root, then
- * check capabilities. If we're root, we already have
- * equivalent capabilities so we don't need to check.
+ * Source port is in the restricted range, and we're not root, we need to set a capability.
+ *
+ * @todo - we really need to call rad_suid_up() and rad_suid_down() here. But those functions
+ * are in src/lib/server/util.c, and we can't require that libfreeradius-bio is linked to
+ * libfreeradius-server.
*/
- if ((my->info.socket.inet.src_port < 1024) && (geteuid() != 0)) {
- (void)fr_cap_enable(CAP_NET_BIND_SERVICE, CAP_EFFECTIVE);
+ if ((my->info.socket.inet.src_port > 0) && (my->info.socket.inet.src_port < 1024) && (geteuid() != 0));
+ (void) fr_cap_enable(CAP_NET_BIND_SERVICE, CAP_EFFECTIVE);
}
#endif
if (fr_bio_fd_socket_bind_to_device(my, cfg) < 0) return -1;
/*
- * Bind to the IP + interface.
+ * Get the sockaddr for bind()
*/
if (fr_ipaddr_to_sockaddr(&salocal, &salen, &my->info.socket.inet.src_ipaddr, my->info.socket.inet.src_port) < 0) return -1;
/*
- * If we have a fixed source port, just use that.
+ * We don't have a source port range, just bind to whatever source port that we're given.
*/
- if (my->info.cfg->src_port || !my->info.cfg->src_port_start) {
+ if (!my->info.cfg->src_port_start) {
if (bind(my->info.socket.fd, (struct sockaddr *) &salocal, salen) < 0) {
fr_strerror_printf("Failed binding to socket: %s", fr_syserror(errno));
return -1;
}
+
} else {
uint16_t src_port, current, range;
struct sockaddr_in *sin = (struct sockaddr_in *) &salocal;
}
/*
- * The source IP may have changed, so get the new one.
+ * The IP and/or port may have changed, so get the new one.
*/
done:
return fr_bio_fd_socket_name(my);