Make tcp_server_create IPv6 aware
This commit is contained in:
parent
71b09488a1
commit
294b8d92c2
1 changed files with 43 additions and 10 deletions
53
src/tcp.c
53
src/tcp.c
|
@ -478,21 +478,55 @@ tcp_server_create(int port, tcp_server_callback_t *start, void *opaque)
|
|||
int fd, x;
|
||||
struct epoll_event e;
|
||||
tcp_server_t *ts;
|
||||
struct sockaddr_in s;
|
||||
struct addrinfo hints, *res, *ressave, *use = NULL;
|
||||
char *portBuf = (char*)malloc(6);
|
||||
int one = 1;
|
||||
int zero = 0;
|
||||
|
||||
memset(&e, 0, sizeof(e));
|
||||
fd = tvh_socket(AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
snprintf(portBuf, 6, "%d", port);
|
||||
|
||||
memset(&hints, 0, sizeof(struct addrinfo));
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
x = getaddrinfo(NULL, portBuf, &hints, &res);
|
||||
free(portBuf);
|
||||
|
||||
if(x != 0)
|
||||
return NULL;
|
||||
|
||||
ressave = res;
|
||||
while(res)
|
||||
{
|
||||
if(res->ai_family == AF_INET6)
|
||||
{
|
||||
use = res;
|
||||
break;
|
||||
}
|
||||
else if(use == NULL)
|
||||
{
|
||||
use = res;
|
||||
}
|
||||
res = res->ai_next;
|
||||
}
|
||||
|
||||
fd = tvh_socket(use->ai_family, use->ai_socktype, use->ai_protocol);
|
||||
if(fd == -1)
|
||||
return NULL;
|
||||
|
||||
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(int));
|
||||
if(use->ai_family == AF_INET6)
|
||||
setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &zero, sizeof(int));
|
||||
|
||||
memset(&s, 0, sizeof(s));
|
||||
s.sin_family = AF_INET;
|
||||
s.sin_port = htons(port);
|
||||
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(int));
|
||||
|
||||
x = bind(fd, (struct sockaddr *)&s, sizeof(s));
|
||||
if(x < 0) {
|
||||
x = bind(fd, use->ai_addr, use->ai_addrlen);
|
||||
freeaddrinfo(ressave);
|
||||
|
||||
if(x != 0)
|
||||
{
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -504,11 +538,10 @@ tcp_server_create(int port, tcp_server_callback_t *start, void *opaque)
|
|||
ts->start = start;
|
||||
ts->opaque = opaque;
|
||||
|
||||
|
||||
e.events = EPOLLIN;
|
||||
e.data.ptr = ts;
|
||||
|
||||
epoll_ctl(tcp_server_epoll_fd, EPOLL_CTL_ADD, fd, &e);
|
||||
|
||||
return ts;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue