... | ... |
@@ -671,6 +671,12 @@ int main(int argc, char **argv) |
671 | 671 |
} |
672 | 672 |
#endif |
673 | 673 |
|
674 |
+ if (nlsockets == 0) { |
|
675 |
+ logg("!Not listening on any interfaces\n"); |
|
676 |
+ ret = 1; |
|
677 |
+ break; |
|
678 |
+ } |
|
679 |
+ |
|
674 | 680 |
ret = recvloop_th(lsockets, nlsockets, engine, dboptions, opts); |
675 | 681 |
|
676 | 682 |
} while (0); |
... | ... |
@@ -55,6 +55,7 @@ int tcpserver(int **lsockets, unsigned int *nlsockets, char *ipaddr, const struc |
55 | 55 |
char *estr, port[10]; |
56 | 56 |
int yes = 1; |
57 | 57 |
int res; |
58 |
+ unsigned int i=0; |
|
58 | 59 |
|
59 | 60 |
sockets = *lsockets; |
60 | 61 |
|
... | ... |
@@ -65,12 +66,23 @@ int tcpserver(int **lsockets, unsigned int *nlsockets, char *ipaddr, const struc |
65 | 65 |
hints.ai_socktype = SOCK_STREAM; |
66 | 66 |
hints.ai_flags = AI_PASSIVE; |
67 | 67 |
|
68 |
+#if C_LINUX |
|
69 |
+ if (!(ipaddr)) { |
|
70 |
+ /* |
|
71 |
+ * By default, getaddrinfo() will return 0.0.0.0 if NULL is passed in as the first parameter. |
|
72 |
+ * Binding to 0.0.0.0 will prevent us from also binding IPv6 ::0 (errno = EADDRINUSE). However, |
|
73 |
+ * if we bind to ::0 (or shorthand, ::), then Linux will bind to both IPv4 and IPv6. |
|
74 |
+ */ |
|
75 |
+ ipaddr = "::"; |
|
76 |
+ } |
|
77 |
+#endif |
|
78 |
+ |
|
68 | 79 |
if ((res = getaddrinfo(ipaddr, port, &hints, &info))) { |
69 | 80 |
logg("!TCP: getaddrinfo: %s\n", gai_strerror(res)); |
70 | 81 |
return -1; |
71 | 82 |
} |
72 | 83 |
|
73 |
- for (p = info; p != NULL; p = p->ai_next) { |
|
84 |
+ for (p = info; p != NULL; p = p->ai_next, i++) { |
|
74 | 85 |
t = realloc(sockets, sizeof(int) * (*nlsockets + 1)); |
75 | 86 |
if (!(t)) { |
76 | 87 |
return -1; |
... | ... |
@@ -89,7 +101,8 @@ int tcpserver(int **lsockets, unsigned int *nlsockets, char *ipaddr, const struc |
89 | 89 |
|
90 | 90 |
if(bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) { |
91 | 91 |
estr = strerror(errno); |
92 |
- logg("!TCP: bind() error when trying to listen on [%s]:%s: %s\n", ipaddr, port, estr); |
|
92 |
+ if (ipaddr || i == 0) |
|
93 |
+ logg("!TCP: bind() error when trying to listen on [%s]:%s: %s\n", ipaddr, port, estr); |
|
93 | 94 |
closesocket(sockfd); |
94 | 95 |
|
95 | 96 |
continue; |
... | ... |
@@ -66,7 +66,7 @@ |
66 | 66 |
|
67 | 67 |
unsigned long int maxstream; |
68 | 68 |
#ifndef _WIN32 |
69 |
-static struct sockaddr_un nixsock; |
|
69 |
+struct sockaddr_un nixsock; |
|
70 | 70 |
#endif |
71 | 71 |
extern struct optstruct *clamdopts; |
72 | 72 |
|
... | ... |
@@ -117,16 +117,35 @@ static int isremote(const struct optstruct *opts) { |
117 | 117 |
continue; |
118 | 118 |
} |
119 | 119 |
|
120 |
- ret = (bind(s, (struct sockaddr *)&testsock, (socklen_t)sizeof(testsock)) != 0); |
|
121 |
- closesocket(s); |
|
120 |
+ switch (p->ai_family) { |
|
121 |
+ case AF_INET: |
|
122 |
+ ((struct sockaddr_in *)(p->ai_addr))->sin_port = htons(INADDR_ANY); |
|
123 |
+ break; |
|
124 |
+ case AF_INET6: |
|
125 |
+ ((struct sockaddr_in6 *)(p->ai_addr))->sin6_port = htons(INADDR_ANY); |
|
126 |
+ break; |
|
127 |
+ default: |
|
128 |
+ break; |
|
129 |
+ } |
|
130 |
+ |
|
131 |
+ ret = bind(s, p->ai_addr, p->ai_addrlen); |
|
122 | 132 |
if (ret) { |
123 |
- /* |
|
124 |
- * If we can't bind, then either we're attempting to listen on an IP that isn't |
|
125 |
- * ours or that clamd is already listening on. |
|
126 |
- */ |
|
133 |
+ if (errno == EADDRINUSE) { |
|
134 |
+ /* |
|
135 |
+ * If we can't bind, then either we're attempting to listen on an IP that isn't |
|
136 |
+ * ours or that clamd is already listening on. |
|
137 |
+ */ |
|
138 |
+ closesocket(s); |
|
139 |
+ freeaddrinfo(info); |
|
140 |
+ return 0; |
|
141 |
+ } |
|
142 |
+ |
|
143 |
+ closesocket(s); |
|
127 | 144 |
freeaddrinfo(info); |
128 | 145 |
return 1; |
129 | 146 |
} |
147 |
+ |
|
148 |
+ closesocket(s); |
|
130 | 149 |
} |
131 | 150 |
|
132 | 151 |
freeaddrinfo(info); |
... | ... |
@@ -134,7 +153,7 @@ static int isremote(const struct optstruct *opts) { |
134 | 134 |
opt = opt->nextarg; |
135 | 135 |
} |
136 | 136 |
|
137 |
- return 1; |
|
137 |
+ return 0; |
|
138 | 138 |
} |
139 | 139 |
|
140 | 140 |
|
... | ... |
@@ -55,6 +55,9 @@ |
55 | 55 |
extern unsigned long int maxstream; |
56 | 56 |
int printinfected; |
57 | 57 |
extern struct optstruct *clamdopts; |
58 |
+#ifndef _WIN32 |
|
59 |
+extern struct sockaddr_un nixsock; |
|
60 |
+#endif |
|
58 | 61 |
|
59 | 62 |
static const char *scancmd[] = { "CONTSCAN", "MULTISCAN", "INSTREAM", "FILDES", "ALLMATCHSCAN" }; |
60 | 63 |
|
... | ... |
@@ -66,6 +69,18 @@ int dconnect() { |
66 | 66 |
struct addrinfo hints, *info, *p; |
67 | 67 |
char port[10]; |
68 | 68 |
|
69 |
+#ifndef _WIN32 |
|
70 |
+ opt = optget(clamdopts, "LocalSocket"); |
|
71 |
+ if (opt->enabled) { |
|
72 |
+ if ((sockd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0) { |
|
73 |
+ if (connect(sockd, (struct sockaddr *)&nixsock, sizeof(nixsock)) == 0) |
|
74 |
+ return sockd; |
|
75 |
+ else |
|
76 |
+ close(sockd); |
|
77 |
+ } |
|
78 |
+ } |
|
79 |
+#endif |
|
80 |
+ |
|
69 | 81 |
snprintf(port, sizeof(port), "%lld", optget(clamdopts, "TCPSocket")->numarg); |
70 | 82 |
|
71 | 83 |
opt = optget(clamdopts, "TCPAddr"); |