...
|
...
|
@@ -49,6 +49,7 @@
|
49
|
49
|
int tcpserver(int **lsockets, unsigned int *nlsockets, char *ipaddr, const struct optstruct *opts)
|
50
|
50
|
{
|
51
|
51
|
struct addrinfo hints, *info, *p;
|
|
52
|
+ char host[NI_MAXHOST], serv[NI_MAXSERV];
|
52
|
53
|
int *sockets;
|
53
|
54
|
int sockfd, backlog;
|
54
|
55
|
int *t;
|
...
|
...
|
@@ -66,19 +67,12 @@ int tcpserver(int **lsockets, unsigned int *nlsockets, char *ipaddr, const struc
|
66
|
66
|
hints.ai_socktype = SOCK_STREAM;
|
67
|
67
|
hints.ai_flags = AI_PASSIVE;
|
68
|
68
|
|
69
|
|
-#if C_LINUX
|
70
|
|
- if (!(ipaddr)) {
|
71
|
|
- /*
|
72
|
|
- * By default, getaddrinfo() will return 0.0.0.0 if NULL is passed in as the first parameter.
|
73
|
|
- * Binding to 0.0.0.0 will prevent us from also binding IPv6 ::0 (errno = EADDRINUSE). However,
|
74
|
|
- * if we bind to ::0 (or shorthand, ::), then Linux will bind to both IPv4 and IPv6.
|
75
|
|
- */
|
76
|
|
- ipaddr = "::";
|
77
|
|
- }
|
|
69
|
+#ifdef AI_ADDRCONFIG
|
|
70
|
+ hints.ai_flags |= AI_ADDRCONFIG;
|
78
|
71
|
#endif
|
79
|
72
|
|
80
|
73
|
if ((res = getaddrinfo(ipaddr, port, &hints, &info))) {
|
81
|
|
- logg("!TCP: getaddrinfo: %s\n", gai_strerror(res));
|
|
74
|
+ logg("!TCP: getaddrinfo failed: %s\n", gai_strerror(res));
|
82
|
75
|
return -1;
|
83
|
76
|
}
|
84
|
77
|
|
...
|
...
|
@@ -102,26 +96,35 @@ int tcpserver(int **lsockets, unsigned int *nlsockets, char *ipaddr, const struc
|
102
|
102
|
logg("!TCP: setsocktopt(SO_REUSEADDR) error: %s\n", strerror(errno));
|
103
|
103
|
}
|
104
|
104
|
|
|
105
|
+#ifdef IPV6_V6ONLY
|
|
106
|
+ if (p->ai_family == AF_INET6 &&
|
|
107
|
+ setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, &yes, sizeof(yes)) == -1) {
|
|
108
|
+ estr = strerror(errno);
|
|
109
|
+ logg("!TCP: setsocktopt(IPV6_V6ONLY) error: %s\n", estr);
|
|
110
|
+ }
|
|
111
|
+#endif /* IPV6_V6ONLY */
|
|
112
|
+
|
|
113
|
+ if ((res = getnameinfo(p->ai_addr, p->ai_addrlen, host, sizeof(host),
|
|
114
|
+ serv, sizeof(serv), NI_NUMERICHOST|NI_NUMERICSERV))) {
|
|
115
|
+ logg("!TCP: getnameinfo failed: %s\n", gai_strerror(res));
|
|
116
|
+ host[0] = '\0';
|
|
117
|
+ serv[0] = '\0';
|
|
118
|
+ }
|
105
|
119
|
if(bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
|
106
|
120
|
estr = strerror(errno);
|
107
|
|
- if (ipaddr || i == 0)
|
108
|
|
- logg("!TCP: bind() error when trying to listen on [%s]:%s: %s\n", ipaddr, port, estr);
|
|
121
|
+ logg("!TCP: Cannot bind to [%s]:%s: %s\n", host, serv, estr);
|
109
|
122
|
closesocket(sockfd);
|
110
|
123
|
|
111
|
124
|
continue;
|
112
|
|
- } else {
|
113
|
|
- if((ipaddr))
|
114
|
|
- logg("#TCP: Bound to address %s on port %u\n", ipaddr, (unsigned int) optget(opts, "TCPSocket")->numarg);
|
115
|
|
- else
|
116
|
|
- logg("#TCP: Bound to port %u\n", (unsigned int) optget(opts, "TCPSocket")->numarg);
|
117
|
125
|
}
|
|
126
|
+ logg("#TCP: Bound to [%s]:%s\n", host, serv);
|
118
|
127
|
|
119
|
128
|
backlog = optget(opts, "MaxConnectionQueueLength")->numarg;
|
120
|
129
|
logg("#TCP: Setting connection queue length to %d\n", backlog);
|
121
|
130
|
|
122
|
131
|
if(listen(sockfd, backlog) == -1) {
|
123
|
132
|
estr = strerror(errno);
|
124
|
|
- logg("!TCP: listen() error: %s\n", estr);
|
|
133
|
+ logg("!TCP: Cannot listen on [%s]:%s: %s\n", host, serv, estr);
|
125
|
134
|
closesocket(sockfd);
|
126
|
135
|
|
127
|
136
|
continue;
|