|
|
|
|
@ -22,24 +22,30 @@ struct rx_info {
|
|
|
|
|
uint8_t tv_set : 1;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static int setsockopt_int(int fd, int level, int option, int val) {
|
|
|
|
|
return setsockopt(fd, level, option, &val, sizeof(val));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int server_init(const struct server_conf *conf, struct server_ctx *ctx) {
|
|
|
|
|
struct sockaddr_in server_addr = { 0 };
|
|
|
|
|
struct sockaddr_in6 server_addr = { 0 };
|
|
|
|
|
int sock_fd;
|
|
|
|
|
int sockopt_int_yes = 1;
|
|
|
|
|
|
|
|
|
|
server_addr.sin_family = AF_INET;
|
|
|
|
|
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
|
|
|
server_addr.sin_port = htons(conf->port);
|
|
|
|
|
server_addr.sin6_family = AF_INET6;
|
|
|
|
|
server_addr.sin6_addr = in6addr_any;
|
|
|
|
|
server_addr.sin6_port = htons(conf->port);
|
|
|
|
|
|
|
|
|
|
if ((sock_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
|
|
|
|
|
if ((sock_fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP)) < 0)
|
|
|
|
|
FAIL("failed to create socket: %s", strerror(errno));
|
|
|
|
|
|
|
|
|
|
if (setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &sockopt_int_yes, sizeof(sockopt_int_yes)))
|
|
|
|
|
if (setsockopt_int(sock_fd, SOL_SOCKET, SO_REUSEADDR, 1))
|
|
|
|
|
FAIL("failed to set SO_REUSEADDR: %s", strerror(errno));
|
|
|
|
|
|
|
|
|
|
if (setsockopt(sock_fd, SOL_SOCKET, SO_TIMESTAMP, &sockopt_int_yes, sizeof(sockopt_int_yes)))
|
|
|
|
|
if (setsockopt_int(sock_fd, SOL_SOCKET, SO_TIMESTAMP, 1))
|
|
|
|
|
FAIL("failed to set SO_TIMESTAMP: %s", strerror(errno));
|
|
|
|
|
|
|
|
|
|
if (setsockopt_int(sock_fd, IPPROTO_IPV6, IPV6_V6ONLY, 0))
|
|
|
|
|
FAIL("failed to set IPV6_V6ONLY: %s", strerror(errno));
|
|
|
|
|
|
|
|
|
|
if (bind(sock_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)))
|
|
|
|
|
FAIL("failed to bind: %s", strerror(errno));
|
|
|
|
|
|
|
|
|
|
|