Browse code

Fix Valgrind. Fix listening on all interfaces on Linux.

Shawn Webb authored on 2014/01/28 04:34:02
Showing 4 changed files
... ...
@@ -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");