bool fr_socket_is_valid_proto(int proto);
int fr_socket_client_unix(char const *path, bool async);
-int fr_socket_client_udp(fr_ipaddr_t const *src_ipaddr, fr_ipaddr_t const *dst_ipaddr,
+int fr_socket_client_udp(fr_ipaddr_t const *src_ipaddr, uint16_t *src_port, fr_ipaddr_t const *dst_ipaddr,
uint16_t dst_port, bool async);
int fr_socket_client_tcp(fr_ipaddr_t const *src_ipaddr, fr_ipaddr_t const *dst_ipaddr,
uint16_t dst_port, bool async);
*
* The following code demonstrates using this function with a connection timeout:
@code {.c}
- sockfd = fr_socket_client_udp(NULL, ipaddr, port, true);
+ sockfd = fr_socket_client_udp(NULL, NULL, ipaddr, port, true);
if (sockfd < 0) {
fr_perror();
exit(1);
*
* @param src_ipaddr to bind socket to, may be NULL if socket is not bound to any specific
* address.
+ * @param[out] src_port The source port we were bound to.
* @param dst_ipaddr Where to send datagrams.
* @param dst_port Where to send datagrams.
* @param async Whether to set the socket to nonblocking, allowing use of
* - FD on success.
* - -1 on failure.
*/
-int fr_socket_client_udp(fr_ipaddr_t const *src_ipaddr, fr_ipaddr_t const *dst_ipaddr, uint16_t dst_port, bool async)
+int fr_socket_client_udp(fr_ipaddr_t const *src_ipaddr, uint16_t *src_port, fr_ipaddr_t const *dst_ipaddr, uint16_t dst_port, bool async)
{
int sockfd;
struct sockaddr_storage salocal;
socklen_t salen;
+ fr_ipaddr_t my_ipaddr;
+ uint16_t my_port;
if (!dst_ipaddr) return -1;
}
#endif
+ if (getsockname(sockfd, (struct sockaddr *) &salocal, &salen) < 0) {
+ fr_strerror_printf("Failed getting socket name: %s", fr_syserror(errno));
+ return -1;
+ }
+
+ if (fr_ipaddr_from_sockaddr(&salocal, salen, &my_ipaddr, &my_port) < 0) return -1;
+ if (src_port) *src_port = my_port;
+
if (connect(sockfd, (struct sockaddr *) &salocal, salen) < 0) {
/*
* POSIX says the only time we will get this,
default:
case IPPROTO_UDP:
- sockfd = fr_socket_client_udp(NULL, &conf->server_ipaddr, conf->server_port, true);
+ sockfd = fr_socket_client_udp(NULL, NULL, &conf->server_ipaddr, conf->server_port, true);
break;
}
if (sockfd < 0) {
DEBUG2("Opening UDP connection to %s:%u", buff, inst->udp.port);
}
- sockfd = fr_socket_client_udp(NULL, &inst->udp.dst_ipaddr, inst->udp.port, true);
+ sockfd = fr_socket_client_udp(NULL, NULL, &inst->udp.dst_ipaddr, inst->udp.port, true);
if (sockfd < 0) {
PERROR("Failed opening UDP socket");
return NULL;
case LOGTEE_DST_UDP:
DEBUG2("Opening UDP connection to %pV:%u",
fr_box_ipaddr(inst->udp.dst_ipaddr), inst->udp.port);
- fd = fr_socket_client_udp(NULL, &inst->udp.dst_ipaddr, inst->udp.port, true);
+ fd = fr_socket_client_udp(NULL, NULL, &inst->udp.dst_ipaddr, inst->udp.port, true);
if (fd < 0) return FR_CONNECTION_STATE_FAILED;
break;
/*
* Open the outgoing socket.
- *
- * @todo - pass src_port, and remove later call to fr_socket_bind()
- * which does return the src_port, but doesn't set the "don't fragment" bit.
*/
- fd = fr_socket_client_udp(&c->src_ipaddr, &c->dst_ipaddr, c->dst_port, true);
+ fd = fr_socket_client_udp(&c->src_ipaddr, &c->src_port, &c->dst_ipaddr, c->dst_port, true);
if (fd < 0) {
DEBUG("%s failed opening socket: %s",
c->inst->parent->name, fr_strerror());
return FR_CONNECTION_STATE_FAILED;
}
-#if 0
- if (fr_socket_bind(fd, &io->src_ipaddr, &io->src_port, inst->interface) < 0) {
- DEBUG("Failed binding RADIUS client UDP socket: %s FD %d %pV port %u interface %s", fr_strerror(), fd, fr_box_ipaddr(io->src_ipaddr),
- io->src_port, inst->interface);
- return FR_CONNECTION_STATE_FAILED;
- }
-#endif
-
/*
* Set the connection name.
*/