int udp_bind(struct sockaddr *sa, in_port_t port) { int s, val; if (socket_af(sa, port) == -1) { log_warn("%s: failed to set UDP port", __func__); return (-1); } if ((s = socket(sa->sa_family, SOCK_DGRAM, IPPROTO_UDP)) == -1) { log_warn("%s: failed to get UDP socket", __func__); return (-1); } /* Skip IPsec processing (don't encrypt) for IKE messages */ if (socket_bypass(s, sa) == -1) { log_warn("%s: failed to bypass IPsec on IKE socket", __func__); goto bad; } val = 1; if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(int)) == -1) { log_warn("%s: failed to set reuseport", __func__); goto bad; } val = 1; if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(int)) == -1) { log_warn("%s: failed to set reuseaddr", __func__); goto bad; } if (sa->sa_family == AF_INET) { val = 1; if (setsockopt(s, IPPROTO_IP, IP_RECVDSTADDR, &val, sizeof(int)) == -1) { log_warn("%s: failed to set IPv4 packet info", __func__); goto bad; } } else { val = 1; if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVPKTINFO, &val, sizeof(int)) == -1) { log_warn("%s: failed to set IPv6 packet info", __func__); goto bad; } } if (bind(s, sa, sa->sa_len) == -1) { log_warn("%s: failed to bind UDP socket", __func__); goto bad; } return (s); bad: close(s); return (-1); }
int udp_bind(struct sockaddr *sa, in_port_t port) { int s, val; if (socket_af(sa, port) == -1) { log_warn("%s: failed to set UDP port", __func__); return (-1); } if ((s = socket(sa->sa_family, SOCK_DGRAM, IPPROTO_UDP)) == -1) { log_warn("%s: failed to get UDP socket", __func__); return (-1); } /* Skip IPsec processing (don't encrypt) for IKE messages */ if (socket_bypass(s, sa) == -1) { log_warn("%s: failed to bypass IPsec on IKE socket", __func__); goto bad; } #ifdef SO_REUSEPORT val = 1; if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(int)) == -1) { log_warn("%s: failed to set reuseport", __func__); goto bad; } #endif #ifdef SO_REUSEADDR val = 1; if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(int)) == -1) { log_warn("%s: failed to set reuseaddr", __func__); goto bad; } #endif if (sa->sa_family == AF_INET) { val = 1; if (setsockopt(s, IPPROTO_IP, #if defined(IP_RECVDSTADDR) IP_RECVDSTADDR, #elif defined(IP_PKTINFO) IP_PKTINFO, #else #error IPv4 packet info not supported #endif &val, sizeof(int)) == -1) { log_warn("%s: failed to set IPv4 packet info", __func__); goto bad; } } else { #ifdef IPV6_V6ONLY val = 1; if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof(int)) == -1) { log_warn("%s: failed to set IPv6-only mode", __func__); goto bad; } #endif val = 1; if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVPKTINFO, &val, sizeof(int)) == -1) { log_warn("%s: failed to set IPv6 packet info", __func__); goto bad; } } if (bind(s, sa, SA_LEN(sa)) == -1) { log_warn("%s: failed to bind UDP socket", __func__); goto bad; } return (s); bad: close(s); return (-1); }