git-svn: trunk@3940
Tomasz Kojm authored on 2008/07/12 03:39:40... | ... |
@@ -1,3 +1,8 @@ |
1 |
+Fri Jul 11 20:14:14 CEST 2008 (tk) |
|
2 |
+---------------------------------- |
|
3 |
+ * freshclam: IPv6 support (bb#715) |
|
4 |
+ * configure: --disable-ipv6 |
|
5 |
+ |
|
1 | 6 |
Thu Jul 10 19:41:37 EEST 2008 (edwin) |
2 | 7 |
------------------------------------- |
3 | 8 |
* unit_tests/: add unit tests for binaries |
... | ... |
@@ -1514,6 +1514,7 @@ Optional Features: |
1514 | 1514 |
--disable-bzip2 disable bzip2 support |
1515 | 1515 |
--disable-rpath do not hardcode runtime library paths |
1516 | 1516 |
--disable-unrar don't build libclamunrar and libclamunrar_iface |
1517 |
+ --disable-ipv6 disable IPv6 support |
|
1517 | 1518 |
--disable-dns disable support for database verification through |
1518 | 1519 |
DNS |
1519 | 1520 |
--disable-clamuko disable clamuko support (Linux, DragonFly and FreeBSD only) |
... | ... |
@@ -4777,7 +4778,7 @@ ia64-*-hpux*) |
4777 | 4777 |
;; |
4778 | 4778 |
*-*-irix6*) |
4779 | 4779 |
# Find out which ABI we are using. |
4780 |
- echo '#line 4780 "configure"' > conftest.$ac_ext |
|
4780 |
+ echo '#line 4781 "configure"' > conftest.$ac_ext |
|
4781 | 4781 |
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 |
4782 | 4782 |
(eval $ac_compile) 2>&5 |
4783 | 4783 |
ac_status=$? |
... | ... |
@@ -6867,11 +6868,11 @@ else |
6867 | 6867 |
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ |
6868 | 6868 |
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ |
6869 | 6869 |
-e 's:$: $lt_compiler_flag:'` |
6870 |
- (eval echo "\"\$as_me:6870: $lt_compile\"" >&5) |
|
6870 |
+ (eval echo "\"\$as_me:6871: $lt_compile\"" >&5) |
|
6871 | 6871 |
(eval "$lt_compile" 2>conftest.err) |
6872 | 6872 |
ac_status=$? |
6873 | 6873 |
cat conftest.err >&5 |
6874 |
- echo "$as_me:6874: \$? = $ac_status" >&5 |
|
6874 |
+ echo "$as_me:6875: \$? = $ac_status" >&5 |
|
6875 | 6875 |
if (exit $ac_status) && test -s "$ac_outfile"; then |
6876 | 6876 |
# The compiler can only warn and ignore the option if not recognized |
6877 | 6877 |
# So say no if there are warnings other than the usual output. |
... | ... |
@@ -7157,11 +7158,11 @@ else |
7157 | 7157 |
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ |
7158 | 7158 |
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ |
7159 | 7159 |
-e 's:$: $lt_compiler_flag:'` |
7160 |
- (eval echo "\"\$as_me:7160: $lt_compile\"" >&5) |
|
7160 |
+ (eval echo "\"\$as_me:7161: $lt_compile\"" >&5) |
|
7161 | 7161 |
(eval "$lt_compile" 2>conftest.err) |
7162 | 7162 |
ac_status=$? |
7163 | 7163 |
cat conftest.err >&5 |
7164 |
- echo "$as_me:7164: \$? = $ac_status" >&5 |
|
7164 |
+ echo "$as_me:7165: \$? = $ac_status" >&5 |
|
7165 | 7165 |
if (exit $ac_status) && test -s "$ac_outfile"; then |
7166 | 7166 |
# The compiler can only warn and ignore the option if not recognized |
7167 | 7167 |
# So say no if there are warnings other than the usual output. |
... | ... |
@@ -7261,11 +7262,11 @@ else |
7261 | 7261 |
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ |
7262 | 7262 |
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ |
7263 | 7263 |
-e 's:$: $lt_compiler_flag:'` |
7264 |
- (eval echo "\"\$as_me:7264: $lt_compile\"" >&5) |
|
7264 |
+ (eval echo "\"\$as_me:7265: $lt_compile\"" >&5) |
|
7265 | 7265 |
(eval "$lt_compile" 2>out/conftest.err) |
7266 | 7266 |
ac_status=$? |
7267 | 7267 |
cat out/conftest.err >&5 |
7268 |
- echo "$as_me:7268: \$? = $ac_status" >&5 |
|
7268 |
+ echo "$as_me:7269: \$? = $ac_status" >&5 |
|
7269 | 7269 |
if (exit $ac_status) && test -s out/conftest2.$ac_objext |
7270 | 7270 |
then |
7271 | 7271 |
# The compiler can only warn and ignore the option if not recognized |
... | ... |
@@ -9638,7 +9639,7 @@ else |
9638 | 9638 |
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 |
9639 | 9639 |
lt_status=$lt_dlunknown |
9640 | 9640 |
cat > conftest.$ac_ext <<EOF |
9641 |
-#line 9641 "configure" |
|
9641 |
+#line 9642 "configure" |
|
9642 | 9642 |
#include "confdefs.h" |
9643 | 9643 |
|
9644 | 9644 |
#if HAVE_DLFCN_H |
... | ... |
@@ -9738,7 +9739,7 @@ else |
9738 | 9738 |
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 |
9739 | 9739 |
lt_status=$lt_dlunknown |
9740 | 9740 |
cat > conftest.$ac_ext <<EOF |
9741 |
-#line 9741 "configure" |
|
9741 |
+#line 9742 "configure" |
|
9742 | 9742 |
#include "confdefs.h" |
9743 | 9743 |
|
9744 | 9744 |
#if HAVE_DLFCN_H |
... | ... |
@@ -15025,6 +15026,97 @@ else |
15025 | 15025 |
fi |
15026 | 15026 |
|
15027 | 15027 |
|
15028 |
+# Check whether --enable-ipv6 was given. |
|
15029 |
+if test "${enable_ipv6+set}" = set; then |
|
15030 |
+ enableval=$enable_ipv6; want_ipv6=$enableval |
|
15031 |
+else |
|
15032 |
+ want_ipv6="yes" |
|
15033 |
+fi |
|
15034 |
+ |
|
15035 |
+ |
|
15036 |
+if test "$want_ipv6" = "yes" |
|
15037 |
+then |
|
15038 |
+ { echo "$as_me:$LINENO: checking for getaddrinfo" >&5 |
|
15039 |
+echo $ECHO_N "checking for getaddrinfo... $ECHO_C" >&6; } |
|
15040 |
+ if test "${have_gai+set}" = set; then |
|
15041 |
+ echo $ECHO_N "(cached) $ECHO_C" >&6 |
|
15042 |
+else |
|
15043 |
+ |
|
15044 |
+ if test "$cross_compiling" = yes; then |
|
15045 |
+ { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling |
|
15046 |
+See \`config.log' for more details." >&5 |
|
15047 |
+echo "$as_me: error: cannot run test program while cross compiling |
|
15048 |
+See \`config.log' for more details." >&2;} |
|
15049 |
+ { (exit 1); exit 1; }; } |
|
15050 |
+else |
|
15051 |
+ cat >conftest.$ac_ext <<_ACEOF |
|
15052 |
+/* confdefs.h. */ |
|
15053 |
+_ACEOF |
|
15054 |
+cat confdefs.h >>conftest.$ac_ext |
|
15055 |
+cat >>conftest.$ac_ext <<_ACEOF |
|
15056 |
+/* end confdefs.h. */ |
|
15057 |
+ |
|
15058 |
+ #include <sys/types.h> |
|
15059 |
+ #include <sys/socket.h> |
|
15060 |
+ #include <netdb.h> |
|
15061 |
+ int main(int argc, char **argv) |
|
15062 |
+ { |
|
15063 |
+ struct addrinfo *res; |
|
15064 |
+ |
|
15065 |
+ if(getaddrinfo("127.0.0.1", NULL, NULL, &res) < 0) |
|
15066 |
+ return 1; |
|
15067 |
+ freeaddrinfo(res); |
|
15068 |
+ return 0; |
|
15069 |
+ } |
|
15070 |
+ |
|
15071 |
+_ACEOF |
|
15072 |
+rm -f conftest$ac_exeext |
|
15073 |
+if { (ac_try="$ac_link" |
|
15074 |
+case "(($ac_try" in |
|
15075 |
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; |
|
15076 |
+ *) ac_try_echo=$ac_try;; |
|
15077 |
+esac |
|
15078 |
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 |
|
15079 |
+ (eval "$ac_link") 2>&5 |
|
15080 |
+ ac_status=$? |
|
15081 |
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 |
|
15082 |
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext' |
|
15083 |
+ { (case "(($ac_try" in |
|
15084 |
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; |
|
15085 |
+ *) ac_try_echo=$ac_try;; |
|
15086 |
+esac |
|
15087 |
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 |
|
15088 |
+ (eval "$ac_try") 2>&5 |
|
15089 |
+ ac_status=$? |
|
15090 |
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 |
|
15091 |
+ (exit $ac_status); }; }; then |
|
15092 |
+ have_gai=yes |
|
15093 |
+else |
|
15094 |
+ echo "$as_me: program exited with status $ac_status" >&5 |
|
15095 |
+echo "$as_me: failed program was:" >&5 |
|
15096 |
+sed 's/^/| /' conftest.$ac_ext >&5 |
|
15097 |
+ |
|
15098 |
+( exit $ac_status ) |
|
15099 |
+have_gai=no |
|
15100 |
+fi |
|
15101 |
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext |
|
15102 |
+fi |
|
15103 |
+ |
|
15104 |
+ |
|
15105 |
+ |
|
15106 |
+fi |
|
15107 |
+ |
|
15108 |
+ { echo "$as_me:$LINENO: result: $have_gai" >&5 |
|
15109 |
+echo "${ECHO_T}$have_gai" >&6; } |
|
15110 |
+ if test "$have_gai" = yes; then |
|
15111 |
+ |
|
15112 |
+cat >>confdefs.h <<\_ACEOF |
|
15113 |
+#define SUPPORT_IPv6 1 |
|
15114 |
+_ACEOF |
|
15115 |
+ |
|
15116 |
+ fi |
|
15117 |
+fi |
|
15118 |
+ |
|
15028 | 15119 |
# Check whether --enable-dns was given. |
15029 | 15120 |
if test "${enable_dns+set}" = set; then |
15030 | 15121 |
enableval=$enable_dns; want_dns=$enableval |
... | ... |
@@ -469,6 +469,37 @@ AC_ARG_ENABLE([unrar], |
469 | 469 |
[ --disable-unrar don't build libclamunrar and libclamunrar_iface ], |
470 | 470 |
want_unrar=$enableval, want_unrar="yes") |
471 | 471 |
|
472 |
+AC_ARG_ENABLE([ipv6], |
|
473 |
+[ --disable-ipv6 disable IPv6 support], |
|
474 |
+want_ipv6=$enableval, want_ipv6="yes") |
|
475 |
+ |
|
476 |
+if test "$want_ipv6" = "yes" |
|
477 |
+then |
|
478 |
+ AC_MSG_CHECKING([for getaddrinfo]) |
|
479 |
+ AC_CACHE_VAL([have_gai],[ |
|
480 |
+ AC_TRY_RUN([ |
|
481 |
+ #include <sys/types.h> |
|
482 |
+ #include <sys/socket.h> |
|
483 |
+ #include <netdb.h> |
|
484 |
+ int main(int argc, char **argv) |
|
485 |
+ { |
|
486 |
+ struct addrinfo *res; |
|
487 |
+ |
|
488 |
+ if(getaddrinfo("127.0.0.1", NULL, NULL, &res) < 0) |
|
489 |
+ return 1; |
|
490 |
+ freeaddrinfo(res); |
|
491 |
+ return 0; |
|
492 |
+ } |
|
493 |
+ ], |
|
494 |
+ [have_gai=yes], |
|
495 |
+ [have_gai=no]) |
|
496 |
+ ]) |
|
497 |
+ AC_MSG_RESULT([$have_gai]) |
|
498 |
+ if test "$have_gai" = yes; then |
|
499 |
+ AC_DEFINE(SUPPORT_IPv6, 1, [Use IPv6 aware code]) |
|
500 |
+ fi |
|
501 |
+fi |
|
502 |
+ |
|
472 | 503 |
AC_ARG_ENABLE([dns], |
473 | 504 |
AC_HELP_STRING([--disable-dns], [disable support for database verification through DNS]), |
474 | 505 |
[want_dns=$enableval], [want_dns=yes] |
... | ... |
@@ -40,6 +40,7 @@ |
40 | 40 |
#ifndef C_WINDOWS |
41 | 41 |
#include <netinet/in.h> |
42 | 42 |
#include <netdb.h> |
43 |
+#include <arpa/inet.h> |
|
43 | 44 |
#endif |
44 | 45 |
#include <sys/types.h> |
45 | 46 |
#ifndef C_WINDOWS |
... | ... |
@@ -82,14 +83,39 @@ |
82 | 82 |
#define closesocket(s) close(s) |
83 | 83 |
#endif |
84 | 84 |
|
85 |
-static int getclientsock(const char *localip) |
|
85 |
+#ifndef SUPPORT_IPv6 |
|
86 |
+static const char *ghbn_err(int err) /* hstrerror() */ |
|
87 |
+{ |
|
88 |
+ switch(err) { |
|
89 |
+ case HOST_NOT_FOUND: |
|
90 |
+ return "Host not found"; |
|
91 |
+ |
|
92 |
+ case NO_DATA: |
|
93 |
+ return "No IP address"; |
|
94 |
+ |
|
95 |
+ case NO_RECOVERY: |
|
96 |
+ return "Unrecoverable DNS error"; |
|
97 |
+ |
|
98 |
+ case TRY_AGAIN: |
|
99 |
+ return "Temporary DNS error"; |
|
100 |
+ |
|
101 |
+ default: |
|
102 |
+ return "Unknown error"; |
|
103 |
+ } |
|
104 |
+} |
|
105 |
+#endif |
|
106 |
+ |
|
107 |
+static int getclientsock(const char *localip, int prot) |
|
86 | 108 |
{ |
87 | 109 |
int socketfd = -1; |
88 | 110 |
|
89 |
-#ifdef PF_INET |
|
90 |
- socketfd = socket(PF_INET, SOCK_STREAM, 0); |
|
111 |
+#ifdef SUPPORT_IPv6 |
|
112 |
+ if(prot == PF_INET6) |
|
113 |
+ socketfd = socket(PF_INET6, SOCK_STREAM, 0); |
|
114 |
+ else |
|
115 |
+ socketfd = socket(PF_INET, SOCK_STREAM, 0); |
|
91 | 116 |
#else |
92 |
- socketfd = socket(AF_INET, SOCK_STREAM, 0); |
|
117 |
+ socketfd = socket(PF_INET, SOCK_STREAM, 0); |
|
93 | 118 |
#endif |
94 | 119 |
|
95 | 120 |
if(socketfd < 0) { |
... | ... |
@@ -98,42 +124,49 @@ static int getclientsock(const char *localip) |
98 | 98 |
} |
99 | 99 |
|
100 | 100 |
if(localip) { |
101 |
- struct hostent *he; |
|
101 |
+#ifdef SUPPORT_IPv6 |
|
102 |
+ struct addrinfo *res; |
|
103 |
+ int ret; |
|
102 | 104 |
|
103 |
- if((he = gethostbyname(localip)) == NULL) { |
|
104 |
- const char *herr; |
|
105 |
- switch(h_errno) { |
|
106 |
- case HOST_NOT_FOUND: |
|
107 |
- herr = "Host not found"; |
|
108 |
- break; |
|
109 |
- |
|
110 |
- case NO_DATA: |
|
111 |
- herr = "No IP address"; |
|
112 |
- break; |
|
105 |
+ ret = getaddrinfo(localip, NULL, NULL, &res); |
|
106 |
+ if(ret) { |
|
107 |
+ logg("!Could not resolve local ip address '%s': %s\n", localip, gai_strerror(ret)); |
|
108 |
+ logg("^Using standard local ip address and port for fetching.\n"); |
|
109 |
+ } else { |
|
110 |
+ char ipaddr[46]; |
|
113 | 111 |
|
114 |
- case NO_RECOVERY: |
|
115 |
- herr = "Unrecoverable DNS error"; |
|
116 |
- break; |
|
112 |
+ if(bind(socketfd, res->ai_addr, res->ai_addrlen) != 0) { |
|
113 |
+ logg("!Could not bind to local ip address '%s': %s\n", localip, strerror(errno)); |
|
114 |
+ logg("^Using default client ip.\n"); |
|
115 |
+ } else { |
|
116 |
+ void *addr; |
|
117 | 117 |
|
118 |
- case TRY_AGAIN: |
|
119 |
- herr = "Temporary DNS error"; |
|
120 |
- break; |
|
118 |
+ if(res->ai_family == AF_INET6) |
|
119 |
+ addr = &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr; |
|
120 |
+ else |
|
121 |
+ addr = &((struct sockaddr_in *) res->ai_addr)->sin_addr; |
|
121 | 122 |
|
122 |
- default: |
|
123 |
- herr = "Unknown error"; |
|
124 |
- break; |
|
123 |
+ if(inet_ntop(res->ai_family, addr, ipaddr, sizeof(ipaddr))) |
|
124 |
+ logg("*Using ip '%s' for fetching.\n", ipaddr); |
|
125 | 125 |
} |
126 |
- logg("!Could not resolve local ip address '%s': %s\n", localip, herr); |
|
126 |
+ freeaddrinfo(res); |
|
127 |
+ } |
|
128 |
+ |
|
129 |
+#else /* IPv4 */ |
|
130 |
+ struct hostent *he; |
|
131 |
+ |
|
132 |
+ if(!(he = gethostbyname(localip))) { |
|
133 |
+ logg("!Could not resolve local ip address '%s': %s\n", localip, ghbn_err(h_errno)); |
|
127 | 134 |
logg("^Using standard local ip address and port for fetching.\n"); |
128 | 135 |
} else { |
129 |
- struct sockaddr_in client; |
|
130 |
- unsigned char *ia; |
|
131 |
- char ipaddr[16]; |
|
136 |
+ struct sockaddr_in client; |
|
137 |
+ unsigned char *ia; |
|
138 |
+ char ipaddr[16]; |
|
132 | 139 |
|
133 |
- memset ((char *) &client, 0, sizeof(struct sockaddr_in)); |
|
140 |
+ memset((char *) &client, 0, sizeof(client)); |
|
134 | 141 |
client.sin_family = AF_INET; |
135 | 142 |
client.sin_addr = *(struct in_addr *) he->h_addr_list[0]; |
136 |
- if (bind(socketfd, (struct sockaddr *) &client, sizeof(struct sockaddr_in)) != 0) { |
|
143 |
+ if(bind(socketfd, (struct sockaddr *) &client, sizeof(struct sockaddr_in)) != 0) { |
|
137 | 144 |
logg("!Could not bind to local ip address '%s': %s\n", localip, strerror(errno)); |
138 | 145 |
logg("^Using default client ip.\n"); |
139 | 146 |
} else { |
... | ... |
@@ -142,6 +175,7 @@ static int getclientsock(const char *localip) |
142 | 142 |
logg("*Using ip '%s' for fetching.\n", ipaddr); |
143 | 143 |
} |
144 | 144 |
} |
145 |
+#endif |
|
145 | 146 |
} |
146 | 147 |
|
147 | 148 |
return socketfd; |
... | ... |
@@ -149,22 +183,21 @@ static int getclientsock(const char *localip) |
149 | 149 |
|
150 | 150 |
static int wwwconnect(const char *server, const char *proxy, int pport, char *ip, const char *localip, int ctimeout, struct mirdat *mdat, int logerr) |
151 | 151 |
{ |
152 |
- int socketfd = -1, port, i, ret; |
|
152 |
+ int socketfd, port, ret; |
|
153 |
+#ifdef SUPPORT_IPv6 |
|
154 |
+ struct addrinfo hints, *res = NULL, *rp; |
|
155 |
+#else |
|
153 | 156 |
struct sockaddr_in name; |
154 | 157 |
struct hostent *host; |
155 |
- char ipaddr[16]; |
|
156 | 158 |
unsigned char *ia; |
159 |
+ int i; |
|
160 |
+#endif |
|
161 |
+ char ipaddr[46]; |
|
157 | 162 |
const char *hostpt; |
158 | 163 |
|
159 | 164 |
if(ip) |
160 | 165 |
strcpy(ip, "???"); |
161 | 166 |
|
162 |
- socketfd = getclientsock(localip); |
|
163 |
- if(socketfd < 0) |
|
164 |
- return -1; |
|
165 |
- |
|
166 |
- name.sin_family = AF_INET; |
|
167 |
- |
|
168 | 167 |
if(proxy) { |
169 | 168 |
hostpt = proxy; |
170 | 169 |
|
... | ... |
@@ -190,31 +223,74 @@ static int wwwconnect(const char *server, const char *proxy, int pport, char *ip |
190 | 190 |
port = 80; |
191 | 191 |
} |
192 | 192 |
|
193 |
- if((host = gethostbyname(hostpt)) == NULL) { |
|
194 |
- const char *herr; |
|
195 |
- switch(h_errno) { |
|
196 |
- case HOST_NOT_FOUND: |
|
197 |
- herr = "Host not found"; |
|
198 |
- break; |
|
193 |
+#ifdef SUPPORT_IPv6 |
|
194 |
+ memset(&hints, 0, sizeof(hints)); |
|
195 |
+ hints.ai_family = AF_UNSPEC; |
|
196 |
+ hints.ai_socktype = SOCK_STREAM; |
|
197 |
+ ret = getaddrinfo(hostpt, "80", &hints, &res); |
|
198 |
+ if(ret) { |
|
199 |
+ logg("%cCan't get information about %s: %s\n", logerr ? '!' : '^', hostpt, gai_strerror(ret)); |
|
200 |
+ return -1; |
|
201 |
+ } |
|
199 | 202 |
|
200 |
- case NO_DATA: |
|
201 |
- herr = "No IP address"; |
|
202 |
- break; |
|
203 |
+ for(rp = res; rp; rp = rp->ai_next) { |
|
204 |
+ void *addr; |
|
203 | 205 |
|
204 |
- case NO_RECOVERY: |
|
205 |
- herr = "Unrecoverable DNS error"; |
|
206 |
- break; |
|
206 |
+ if(rp->ai_family == AF_INET6) |
|
207 |
+ addr = &((struct sockaddr_in6 *) rp->ai_addr)->sin6_addr; |
|
208 |
+ else |
|
209 |
+ addr = &((struct sockaddr_in *) rp->ai_addr)->sin_addr; |
|
207 | 210 |
|
208 |
- case TRY_AGAIN: |
|
209 |
- herr = "Temporary DNS error"; |
|
210 |
- break; |
|
211 |
+ if(!inet_ntop(rp->ai_family, addr, ipaddr, sizeof(ipaddr))) { |
|
212 |
+ logg("%cinet_ntop() failed\n", logerr ? '!' : '^'); |
|
213 |
+ freeaddrinfo(res); |
|
214 |
+ return -1; |
|
215 |
+ } |
|
211 | 216 |
|
212 |
- default: |
|
213 |
- herr = "Unknown error"; |
|
214 |
- break; |
|
217 |
+ if((ret = mirman_check(addr, rp->ai_family, mdat))) { |
|
218 |
+ if(ret == 1) |
|
219 |
+ logg("Ignoring mirror %s (due to previous errors)\n", ipaddr); |
|
220 |
+ else |
|
221 |
+ logg("Ignoring mirror %s (has connected too many times with an outdated version)\n", ipaddr); |
|
222 |
+ continue; |
|
215 | 223 |
} |
216 |
- logg("%cCan't get information about %s: %s\n", logerr ? '!' : '^', hostpt, herr); |
|
217 |
- closesocket(socketfd); |
|
224 |
+ |
|
225 |
+ if(ip) |
|
226 |
+ strcpy(ip, ipaddr); |
|
227 |
+ |
|
228 |
+ if(rp != res) |
|
229 |
+ logg("Trying host %s (%s)...\n", hostpt, ipaddr); |
|
230 |
+ |
|
231 |
+ socketfd = getclientsock(localip, rp->ai_family); |
|
232 |
+ if(socketfd < 0) { |
|
233 |
+ freeaddrinfo(res); |
|
234 |
+ return -1; |
|
235 |
+ } |
|
236 |
+ |
|
237 |
+#ifdef SO_ERROR |
|
238 |
+ if(wait_connect(socketfd, rp->ai_addr, rp->ai_addrlen, ctimeout) == -1) { |
|
239 |
+#else |
|
240 |
+ if(connect(socketfd, rp->ai_addr, rp->ai_addrlen) == -1) { |
|
241 |
+#endif |
|
242 |
+ logg("Can't connect to port %d of host %s (IP: %s)\n", port, hostpt, ipaddr); |
|
243 |
+ closesocket(socketfd); |
|
244 |
+ continue; |
|
245 |
+ } else { |
|
246 |
+ if(rp->ai_family == AF_INET) |
|
247 |
+ mdat->currip[0] = *((uint32_t *) addr); |
|
248 |
+ else |
|
249 |
+ memcpy(mdat->currip, addr, 4); |
|
250 |
+ mdat->af = rp->ai_family; |
|
251 |
+ freeaddrinfo(res); |
|
252 |
+ return socketfd; |
|
253 |
+ } |
|
254 |
+ } |
|
255 |
+ freeaddrinfo(res); |
|
256 |
+ |
|
257 |
+#else /* IPv4 */ |
|
258 |
+ |
|
259 |
+ if((host = gethostbyname(hostpt)) == NULL) { |
|
260 |
+ logg("%cCan't get information about %s: %s\n", logerr ? '!' : '^', hostpt, ghbn_err(h_errno)); |
|
218 | 261 |
return -1; |
219 | 262 |
} |
220 | 263 |
|
... | ... |
@@ -223,7 +299,7 @@ static int wwwconnect(const char *server, const char *proxy, int pport, char *ip |
223 | 223 |
ia = (unsigned char *) host->h_addr_list[i]; |
224 | 224 |
sprintf(ipaddr, "%u.%u.%u.%u", ia[0], ia[1], ia[2], ia[3]); |
225 | 225 |
|
226 |
- if((ret = mirman_check(((struct in_addr *) ia)->s_addr, mdat))) { |
|
226 |
+ if((ret = mirman_check(&((struct in_addr *) ia)->s_addr, AF_INET, mdat))) { |
|
227 | 227 |
if(ret == 1) |
228 | 228 |
logg("Ignoring mirror %s (due to previous errors)\n", ipaddr); |
229 | 229 |
else |
... | ... |
@@ -237,9 +313,15 @@ static int wwwconnect(const char *server, const char *proxy, int pport, char *ip |
237 | 237 |
if(i > 0) |
238 | 238 |
logg("Trying host %s (%s)...\n", hostpt, ipaddr); |
239 | 239 |
|
240 |
+ memset ((char *) &name, 0, sizeof(name)); |
|
241 |
+ name.sin_family = AF_INET; |
|
240 | 242 |
name.sin_addr = *((struct in_addr *) host->h_addr_list[i]); |
241 | 243 |
name.sin_port = htons(port); |
242 | 244 |
|
245 |
+ socketfd = getclientsock(localip, AF_INET); |
|
246 |
+ if(socketfd < 0) |
|
247 |
+ return -1; |
|
248 |
+ |
|
243 | 249 |
#ifdef SO_ERROR |
244 | 250 |
if(wait_connect(socketfd, (struct sockaddr *) &name, sizeof(struct sockaddr_in), ctimeout) == -1) { |
245 | 251 |
#else |
... | ... |
@@ -247,17 +329,15 @@ static int wwwconnect(const char *server, const char *proxy, int pport, char *ip |
247 | 247 |
#endif |
248 | 248 |
logg("Can't connect to port %d of host %s (IP: %s)\n", port, hostpt, ipaddr); |
249 | 249 |
closesocket(socketfd); |
250 |
- if((socketfd = getclientsock(localip)) == -1) |
|
251 |
- return -1; |
|
252 |
- |
|
253 | 250 |
continue; |
254 | 251 |
} else { |
255 |
- mdat->currip = ((struct in_addr *) ia)->s_addr; |
|
252 |
+ mdat->currip[0] = ((struct in_addr *) ia)->s_addr; |
|
253 |
+ mdat->af = AF_INET; |
|
256 | 254 |
return socketfd; |
257 | 255 |
} |
258 | 256 |
} |
257 |
+#endif |
|
259 | 258 |
|
260 |
- closesocket(socketfd); |
|
261 | 259 |
return -2; |
262 | 260 |
} |
263 | 261 |
|
... | ... |
@@ -339,7 +419,7 @@ static char *proxyauth(const char *user, const char *pass) |
339 | 339 |
|
340 | 340 |
static struct cl_cvd *remote_cvdhead(const char *file, const char *hostname, char *ip, const char *localip, const char *proxy, int port, const char *user, const char *pass, const char *uas, int *ims, int ctimeout, int rtimeout, struct mirdat *mdat, int logerr) |
341 | 341 |
{ |
342 |
- char cmd[512], head[513], buffer[FILEBUFF], ipaddr[16], *ch, *tmp; |
|
342 |
+ char cmd[512], head[513], buffer[FILEBUFF], ipaddr[46], *ch, *tmp; |
|
343 | 343 |
int bread, cnt, sd; |
344 | 344 |
unsigned int i, j; |
345 | 345 |
char *remotename = NULL, *authorization = NULL; |
... | ... |
@@ -437,7 +517,7 @@ static struct cl_cvd *remote_cvdhead(const char *file, const char *hostname, cha |
437 | 437 |
|
438 | 438 |
if(bread == -1) { |
439 | 439 |
logg("%cremote_cvdhead: Error while reading CVD header from %s\n", logerr ? '!' : '^', hostname); |
440 |
- mirman_update(mdat->currip, mdat, 1); |
|
440 |
+ mirman_update(mdat->currip, mdat->af, mdat, 1); |
|
441 | 441 |
return NULL; |
442 | 442 |
} |
443 | 443 |
|
... | ... |
@@ -451,7 +531,7 @@ static struct cl_cvd *remote_cvdhead(const char *file, const char *hostname, cha |
451 | 451 |
if((strstr(buffer, "HTTP/1.1 304")) != NULL || (strstr(buffer, "HTTP/1.0 304")) != NULL) { |
452 | 452 |
*ims = 0; |
453 | 453 |
logg("OK (IMS)\n"); |
454 |
- mirman_update(mdat->currip, mdat, 0); |
|
454 |
+ mirman_update(mdat->currip, mdat->af, mdat, 0); |
|
455 | 455 |
return NULL; |
456 | 456 |
} else { |
457 | 457 |
*ims = 1; |
... | ... |
@@ -460,7 +540,7 @@ static struct cl_cvd *remote_cvdhead(const char *file, const char *hostname, cha |
460 | 460 |
if(!strstr(buffer, "HTTP/1.1 200") && !strstr(buffer, "HTTP/1.0 200") && |
461 | 461 |
!strstr(buffer, "HTTP/1.1 206") && !strstr(buffer, "HTTP/1.0 206")) { |
462 | 462 |
logg("%cUnknown response from remote server\n", logerr ? '!' : '^'); |
463 |
- mirman_update(mdat->currip, mdat, 1); |
|
463 |
+ mirman_update(mdat->currip, mdat->af, mdat, 1); |
|
464 | 464 |
return NULL; |
465 | 465 |
} |
466 | 466 |
|
... | ... |
@@ -478,7 +558,7 @@ static struct cl_cvd *remote_cvdhead(const char *file, const char *hostname, cha |
478 | 478 |
|
479 | 479 |
if(sizeof(buffer) - i < 512) { |
480 | 480 |
logg("%cremote_cvdhead: Malformed CVD header (too short)\n", logerr ? '!' : '^'); |
481 |
- mirman_update(mdat->currip, mdat, 1); |
|
481 |
+ mirman_update(mdat->currip, mdat->af, mdat, 1); |
|
482 | 482 |
return NULL; |
483 | 483 |
} |
484 | 484 |
|
... | ... |
@@ -487,7 +567,7 @@ static struct cl_cvd *remote_cvdhead(const char *file, const char *hostname, cha |
487 | 487 |
for(j = 0; j < 512; j++) { |
488 | 488 |
if(!ch || (ch && !*ch) || (ch && !isprint(ch[j]))) { |
489 | 489 |
logg("%cremote_cvdhead: Malformed CVD header (bad chars)\n", logerr ? '!' : '^'); |
490 |
- mirman_update(mdat->currip, mdat, 1); |
|
490 |
+ mirman_update(mdat->currip, mdat->af, mdat, 1); |
|
491 | 491 |
return NULL; |
492 | 492 |
} |
493 | 493 |
head[j] = ch[j]; |
... | ... |
@@ -495,10 +575,10 @@ static struct cl_cvd *remote_cvdhead(const char *file, const char *hostname, cha |
495 | 495 |
|
496 | 496 |
if(!(cvd = cl_cvdparse(head))) { |
497 | 497 |
logg("%cremote_cvdhead: Malformed CVD header (can't parse)\n", logerr ? '!' : '^'); |
498 |
- mirman_update(mdat->currip, mdat, 1); |
|
498 |
+ mirman_update(mdat->currip, mdat->af, mdat, 1); |
|
499 | 499 |
} else { |
500 | 500 |
logg("OK\n"); |
501 |
- mirman_update(mdat->currip, mdat, 0); |
|
501 |
+ mirman_update(mdat->currip, mdat->af, mdat, 0); |
|
502 | 502 |
} |
503 | 503 |
|
504 | 504 |
return cvd; |
... | ... |
@@ -587,7 +667,7 @@ static int getfile(const char *srcfile, const char *destfile, const char *hostna |
587 | 587 |
if((i >= sizeof(buffer) - 1) || recv(sd, buffer + i, 1, 0) == -1) { |
588 | 588 |
#endif |
589 | 589 |
logg("%cgetfile: Error while reading database from %s (IP: %s)\n", logerr ? '!' : '^', hostname, ipaddr); |
590 |
- mirman_update(mdat->currip, mdat, 1); |
|
590 |
+ mirman_update(mdat->currip, mdat->af, mdat, 1); |
|
591 | 591 |
closesocket(sd); |
592 | 592 |
return 52; |
593 | 593 |
} |
... | ... |
@@ -613,7 +693,7 @@ static int getfile(const char *srcfile, const char *destfile, const char *hostna |
613 | 613 |
if(!strstr(buffer, "HTTP/1.1 200") && !strstr(buffer, "HTTP/1.0 200") && |
614 | 614 |
!strstr(buffer, "HTTP/1.1 206") && !strstr(buffer, "HTTP/1.0 206")) { |
615 | 615 |
logg("%cgetfile: Unknown response from remote server (IP: %s)\n", logerr ? '!' : '^', ipaddr); |
616 |
- mirman_update(mdat->currip, mdat, 1); |
|
616 |
+ mirman_update(mdat->currip, mdat->af, mdat, 1); |
|
617 | 617 |
closesocket(sd); |
618 | 618 |
return 58; |
619 | 619 |
} |
... | ... |
@@ -678,7 +758,7 @@ static int getfile(const char *srcfile, const char *destfile, const char *hostna |
678 | 678 |
else |
679 | 679 |
logg("Downloading %s [*]\n", srcfile); |
680 | 680 |
|
681 |
- mirman_update(mdat->currip, mdat, 0); |
|
681 |
+ mirman_update(mdat->currip, mdat->af, mdat, 0); |
|
682 | 682 |
return 0; |
683 | 683 |
} |
684 | 684 |
|
... | ... |
@@ -1203,7 +1283,7 @@ int downloadmanager(const struct cfgstruct *copt, const struct optstruct *opt, c |
1203 | 1203 |
time_t currtime; |
1204 | 1204 |
int ret, updated = 0, outdated = 0, signo = 0; |
1205 | 1205 |
unsigned int ttl; |
1206 |
- char ipaddr[16], *dnsreply = NULL, *pt, *localip = NULL, *newver = NULL; |
|
1206 |
+ char ipaddr[46], *dnsreply = NULL, *pt, *localip = NULL, *newver = NULL; |
|
1207 | 1207 |
const char *arg = NULL; |
1208 | 1208 |
const struct cfgstruct *cpt; |
1209 | 1209 |
struct mirdat mdat; |
... | ... |
@@ -1213,6 +1293,9 @@ int downloadmanager(const struct cfgstruct *copt, const struct optstruct *opt, c |
1213 | 1213 |
|
1214 | 1214 |
time(&currtime); |
1215 | 1215 |
logg("ClamAV update process started at %s", ctime(&currtime)); |
1216 |
+#ifdef SUPPORT_IPv6 |
|
1217 |
+ logg("*Using IPv6 aware code\n"); |
|
1218 |
+#endif |
|
1216 | 1219 |
|
1217 | 1220 |
#ifndef HAVE_LIBGMP |
1218 | 1221 |
logg("SECURITY WARNING: NO SUPPORT FOR DIGITAL SIGNATURES\n"); |
... | ... |
@@ -35,6 +35,10 @@ |
35 | 35 |
#include <fcntl.h> |
36 | 36 |
#include <time.h> |
37 | 37 |
|
38 |
+#include <sys/socket.h> |
|
39 |
+#include <netinet/in.h> |
|
40 |
+#include <arpa/inet.h> |
|
41 |
+ |
|
38 | 42 |
#include "mirman.h" |
39 | 43 |
|
40 | 44 |
#include "libclamav/cltypes.h" |
... | ... |
@@ -94,7 +98,7 @@ int mirman_read(const char *file, struct mirdat *mdat, uint8_t active) |
94 | 94 |
return 0; |
95 | 95 |
} |
96 | 96 |
|
97 |
-int mirman_check(uint32_t ip, struct mirdat *mdat) |
|
97 |
+int mirman_check(uint32_t *ip, int af, struct mirdat *mdat) |
|
98 | 98 |
{ |
99 | 99 |
unsigned int i, flevel = cl_retflevel(); |
100 | 100 |
|
... | ... |
@@ -103,7 +107,8 @@ int mirman_check(uint32_t ip, struct mirdat *mdat) |
103 | 103 |
return 0; |
104 | 104 |
|
105 | 105 |
for(i = 0; i < mdat->num; i++) { |
106 |
- if(mdat->mirtab[i].atime && mdat->mirtab[i].ip == ip) { |
|
106 |
+ |
|
107 |
+ if(mdat->mirtab[i].atime && ((af == AF_INET && mdat->mirtab[i].ip4 == *ip) || (af == AF_INET6 && !memcmp(mdat->mirtab[i].ip6, ip, 4)))) { |
|
107 | 108 |
|
108 | 109 |
if(mdat->dbflevel && (mdat->dbflevel > flevel) && (mdat->dbflevel - flevel > 3)) |
109 | 110 |
if(time(NULL) - mdat->mirtab[i].atime < 4 * 3600) |
... | ... |
@@ -123,7 +128,7 @@ int mirman_check(uint32_t ip, struct mirdat *mdat) |
123 | 123 |
return 0; |
124 | 124 |
} |
125 | 125 |
|
126 |
-int mirman_update(uint32_t ip, struct mirdat *mdat, uint8_t broken) |
|
126 |
+int mirman_update(uint32_t *ip, int af, struct mirdat *mdat, uint8_t broken) |
|
127 | 127 |
{ |
128 | 128 |
unsigned int i, found = 0; |
129 | 129 |
|
... | ... |
@@ -132,7 +137,7 @@ int mirman_update(uint32_t ip, struct mirdat *mdat, uint8_t broken) |
132 | 132 |
return 0; |
133 | 133 |
|
134 | 134 |
for(i = 0; i < mdat->num; i++) { |
135 |
- if(mdat->mirtab[i].ip == ip) { |
|
135 |
+ if((af == AF_INET && mdat->mirtab[i].ip4 == *ip) || (af == AF_INET6 && !memcmp(mdat->mirtab[i].ip6, ip, 4))) { |
|
136 | 136 |
found = 1; |
137 | 137 |
break; |
138 | 138 |
} |
... | ... |
@@ -160,7 +165,12 @@ int mirman_update(uint32_t ip, struct mirdat *mdat, uint8_t broken) |
160 | 160 |
logg("!Can't allocate memory for new element in mdat->mirtab\n"); |
161 | 161 |
return -1; |
162 | 162 |
} |
163 |
- mdat->mirtab[mdat->num].ip = ip; |
|
163 |
+ if(af == AF_INET) { |
|
164 |
+ mdat->mirtab[mdat->num].ip4 = *ip; |
|
165 |
+ } else { |
|
166 |
+ mdat->mirtab[mdat->num].ip4 = 0; |
|
167 |
+ memcpy(mdat->mirtab[mdat->num].ip6, ip, 4); |
|
168 |
+ } |
|
164 | 169 |
mdat->mirtab[mdat->num].atime = 0; |
165 | 170 |
mdat->mirtab[mdat->num].succ = 0; |
166 | 171 |
mdat->mirtab[mdat->num].fail = 0; |
... | ... |
@@ -179,14 +189,16 @@ int mirman_update(uint32_t ip, struct mirdat *mdat, uint8_t broken) |
179 | 179 |
void mirman_list(const struct mirdat *mdat) |
180 | 180 |
{ |
181 | 181 |
unsigned int i; |
182 |
- unsigned char *ip; |
|
183 | 182 |
time_t tm; |
183 |
+ char ip[46]; |
|
184 | 184 |
|
185 | 185 |
|
186 | 186 |
for(i = 0; i < mdat->num; i++) { |
187 | 187 |
printf("Mirror #%u\n", i + 1); |
188 |
- ip = (unsigned char *) &mdat->mirtab[i].ip; |
|
189 |
- printf("IP: %u.%u.%u.%u\n", ip[0], ip[1], ip[2], ip[3]); |
|
188 |
+ if(mdat->mirtab[i].ip4) |
|
189 |
+ printf("IP: %s\n", inet_ntop(AF_INET, &mdat->mirtab[i].ip4, ip, sizeof(ip))); |
|
190 |
+ else |
|
191 |
+ printf("IP: %s\n", inet_ntop(AF_INET6, mdat->mirtab[i].ip6, ip, sizeof(ip))); |
|
190 | 192 |
printf("Successes: %u\n", mdat->mirtab[i].succ); |
191 | 193 |
printf("Failures: %u\n", mdat->mirtab[i].fail); |
192 | 194 |
tm = mdat->mirtab[i].atime; |
... | ... |
@@ -22,25 +22,27 @@ |
22 | 22 |
#include "libclamav/cltypes.h" |
23 | 23 |
|
24 | 24 |
struct mirdat_ip { |
25 |
- uint32_t ip; /* IP address */ |
|
25 |
+ uint32_t ip4; /* IPv4 address */ |
|
26 | 26 |
uint32_t atime; /* last access time */ |
27 | 27 |
uint32_t succ; /* number of successful downloads from this ip */ |
28 | 28 |
uint32_t fail; /* number of failures */ |
29 | 29 |
uint8_t ignore; /* ignore flag */ |
30 |
- char res[32]; /* reserved */ |
|
30 |
+ uint32_t ip6[4]; /* IPv6 address */ |
|
31 |
+ char res[16]; /* reserved */ |
|
31 | 32 |
}; |
32 | 33 |
|
33 | 34 |
struct mirdat { |
34 | 35 |
uint8_t active; |
35 | 36 |
unsigned int num; |
36 |
- uint32_t currip; |
|
37 |
+ uint32_t currip[4]; |
|
38 |
+ uint32_t af; |
|
37 | 39 |
uint32_t dbflevel; |
38 | 40 |
struct mirdat_ip *mirtab; |
39 | 41 |
}; |
40 | 42 |
|
41 | 43 |
int mirman_read(const char *file, struct mirdat *mdat, uint8_t active); |
42 |
-int mirman_check(uint32_t ip, struct mirdat *mdat); |
|
43 |
-int mirman_update(uint32_t ip, struct mirdat *mdat, uint8_t broken); |
|
44 |
+int mirman_check(uint32_t *ip, int af, struct mirdat *mdat); |
|
45 |
+int mirman_update(uint32_t *ip, int af, struct mirdat *mdat, uint8_t broken); |
|
44 | 46 |
void mirman_list(const struct mirdat *mdat); |
45 | 47 |
int mirman_write(const char *file, struct mirdat *mdat); |
46 | 48 |
void mirman_free(struct mirdat *mdat); |
... | ... |
@@ -55,8 +55,15 @@ int notify(const char *cfgfile) |
55 | 55 |
#ifndef C_WINDOWS |
56 | 56 |
struct sockaddr_un server; |
57 | 57 |
#endif |
58 |
+#ifdef SUPPORT_IPv6 |
|
59 |
+ struct addrinfo hints, *res; |
|
60 |
+ char port[6]; |
|
61 |
+ const char *addr; |
|
62 |
+ int ret; |
|
63 |
+#else |
|
58 | 64 |
struct sockaddr_in server2; |
59 | 65 |
struct hostent *he; |
66 |
+#endif |
|
60 | 67 |
struct cfgstruct *copt; |
61 | 68 |
const struct cfgstruct *cpt; |
62 | 69 |
int sockd, bread; |
... | ... |
@@ -93,8 +100,49 @@ int notify(const char *cfgfile) |
93 | 93 |
} else |
94 | 94 |
#endif |
95 | 95 |
if((cpt = cfgopt(copt, "TCPSocket"))->enabled) { |
96 |
- |
|
97 | 96 |
socktype = "TCP"; |
97 |
+ |
|
98 |
+#if SUPPORT_IPv6 |
|
99 |
+ memset(&hints, 0, sizeof(hints)); |
|
100 |
+ hints.ai_family = AF_UNSPEC; |
|
101 |
+ hints.ai_socktype = SOCK_STREAM; |
|
102 |
+ snprintf(port, 5, "%d", cpt->numarg); |
|
103 |
+ port[5] = 0; |
|
104 |
+ |
|
105 |
+ if((cpt = cfgopt(copt, "TCPAddr"))->enabled) |
|
106 |
+ addr = cpt->strarg; |
|
107 |
+ else |
|
108 |
+ addr = NULL; |
|
109 |
+ |
|
110 |
+ ret = getaddrinfo(addr, port, &hints, &res); |
|
111 |
+ |
|
112 |
+ if(ret) { |
|
113 |
+ perror("getaddrinfo()"); |
|
114 |
+ logg("^Clamd was NOT notified: Can't resolve hostname %s\n", addr ? addr : ""); |
|
115 |
+ freecfg(copt); |
|
116 |
+ return 1; |
|
117 |
+ } |
|
118 |
+ |
|
119 |
+ if((sockd = socket(res->ai_family, SOCK_STREAM, 0)) < 0) { |
|
120 |
+ perror("socket()"); |
|
121 |
+ logg("^Clamd was NOT notified: Can't create TCP socket\n"); |
|
122 |
+ freecfg(copt); |
|
123 |
+ freeaddrinfo(res); |
|
124 |
+ return 1; |
|
125 |
+ } |
|
126 |
+ |
|
127 |
+ if(connect(sockd, res->ai_addr, res->ai_addrlen) == -1) { |
|
128 |
+ perror("connect()"); |
|
129 |
+ closesocket(sockd); |
|
130 |
+ logg("^Clamd was NOT notified: Can't connect to clamd on %s:%s\n", addr, port); |
|
131 |
+ freecfg(copt); |
|
132 |
+ freeaddrinfo(res); |
|
133 |
+ return 1; |
|
134 |
+ } |
|
135 |
+ freeaddrinfo(res); |
|
136 |
+ |
|
137 |
+#else /* IPv4 */ |
|
138 |
+ |
|
98 | 139 |
#ifdef PF_INET |
99 | 140 |
if((sockd = socket(PF_INET, SOCK_STREAM, 0)) < 0) { |
100 | 141 |
#else |
... | ... |
@@ -110,10 +158,11 @@ int notify(const char *cfgfile) |
110 | 110 |
server2.sin_port = htons(cpt->numarg); |
111 | 111 |
|
112 | 112 |
if((cpt = cfgopt(copt, "TCPAddr"))->enabled) { |
113 |
- if ((he = gethostbyname(cpt->strarg)) == 0) { |
|
113 |
+ if((he = gethostbyname(cpt->strarg)) == 0) { |
|
114 | 114 |
perror("gethostbyname()"); |
115 | 115 |
logg("^Clamd was NOT notified: Can't resolve hostname '%s'\n", cpt->strarg); |
116 | 116 |
freecfg(copt); |
117 |
+ closesocket(sockd); |
|
117 | 118 |
return 1; |
118 | 119 |
} |
119 | 120 |
server2.sin_addr = *(struct in_addr *) he->h_addr_list[0]; |
... | ... |
@@ -130,6 +179,8 @@ int notify(const char *cfgfile) |
130 | 130 |
return 1; |
131 | 131 |
} |
132 | 132 |
|
133 |
+#endif |
|
134 |
+ |
|
133 | 135 |
} else { |
134 | 136 |
logg("^Clamd was NOT notified: No socket specified in %s\n", cfgfile); |
135 | 137 |
freecfg(copt); |