... | ... |
@@ -1,3 +1,7 @@ |
1 |
+Wed Apr 27 15:07:22 CEST 2011 (tk) |
|
2 |
+---------------------------------- |
|
3 |
+ * freshclam: add mirror statistics mechanism |
|
4 |
+ |
|
1 | 5 |
Mon Apr 18 17:23:10 CEST 2011 (acab) |
2 | 6 |
------------------------------------ |
3 | 7 |
* clamd, win32: Conversion to UTF8 is hopefully completefinal. |
... | ... |
@@ -41,11 +41,11 @@ |
41 | 41 |
#define PACKETSZ 512 |
42 | 42 |
#endif |
43 | 43 |
|
44 |
-char *txtquery(const char *domain, unsigned int *ttl) |
|
44 |
+char *dnsquery(const char *domain, int qtype, unsigned int *ttl) |
|
45 | 45 |
{ |
46 | 46 |
unsigned char answer[PACKETSZ], *answend, *pt; |
47 | 47 |
char *txt, host[128]; |
48 |
- int len, type, qtype; |
|
48 |
+ int len, type; |
|
49 | 49 |
unsigned int cttl, size, txtlen = 0; |
50 | 50 |
|
51 | 51 |
|
... | ... |
@@ -59,7 +59,6 @@ char *txtquery(const char *domain, unsigned int *ttl) |
59 | 59 |
logg("*Querying %s\n", domain); |
60 | 60 |
|
61 | 61 |
memset(answer, 0, PACKETSZ); |
62 |
- qtype = T_TXT; |
|
63 | 62 |
if((len = res_query(domain, C_IN, qtype, answer, PACKETSZ)) < 0 || len > PACKETSZ) { |
64 | 63 |
#ifdef FRESHCLAM_DNS_FIX |
65 | 64 |
/* The DNS server in the SpeedTouch Alcatel 510 modem can't |
... | ... |
@@ -68,16 +67,22 @@ char *txtquery(const char *domain, unsigned int *ttl) |
68 | 68 |
* to resolve normally only has a TXT-record anyway. |
69 | 69 |
*/ |
70 | 70 |
memset(answer, 0, PACKETSZ); |
71 |
- qtype=T_ANY; |
|
71 |
+ if(qtype == T_TXT) |
|
72 |
+ qtype = T_ANY; |
|
72 | 73 |
if((len = res_query(domain, C_IN, qtype, answer, PACKETSZ)) < 0) { |
73 |
- logg("^Can't query %s\n", domain); |
|
74 |
+ logg("%cCan't query %s\n", (qtype == T_TXT || qtype == T_ANY) ? '^' : '*', domain); |
|
74 | 75 |
return NULL; |
75 | 76 |
} |
76 | 77 |
#else |
77 |
- logg("^Can't query %s\n", domain); |
|
78 |
+ logg("%cCan't query %s\n", (qtype == T_TXT) ? '^' : '*', domain); |
|
78 | 79 |
return NULL; |
79 | 80 |
#endif |
80 | 81 |
} |
82 |
+ if(qtype != T_TXT && qtype != T_ANY) { |
|
83 |
+ if(ttl) |
|
84 |
+ *ttl = 2; |
|
85 |
+ return NULL; |
|
86 |
+ } |
|
81 | 87 |
|
82 | 88 |
answend = answer + len; |
83 | 89 |
pt = answer + sizeof(HEADER); |
... | ... |
@@ -145,9 +150,10 @@ char *txtquery(const char *domain, unsigned int *ttl) |
145 | 145 |
|
146 | 146 |
#else |
147 | 147 |
|
148 |
-char *txtquery(const char *domain, unsigned int *ttl) |
|
148 |
+char *dnsquery(const char *domain, int qtype, unsigned int *ttl) |
|
149 | 149 |
{ |
150 |
- *ttl = 1; /* ttl of 1 combined with a NULL return distinguishes a failed lookup from DNS queries not being available */ |
|
150 |
+ if(ttl) |
|
151 |
+ *ttl = 1; /* ttl of 1 combined with a NULL return distinguishes a failed lookup from DNS queries not being available */ |
|
151 | 152 |
return NULL; |
152 | 153 |
} |
153 | 154 |
|
... | ... |
@@ -20,6 +20,18 @@ |
20 | 20 |
#ifndef __DNS_H |
21 | 21 |
#define __DNS_H |
22 | 22 |
|
23 |
-char *txtquery(const char *domain, unsigned int *ttl); |
|
23 |
+#if HAVE_CONFIG_H |
|
24 |
+#include "clamav-config.h" |
|
25 |
+#endif |
|
26 |
+ |
|
27 |
+#ifdef HAVE_RESOLV_H |
|
28 |
+#ifndef _WIN32 |
|
29 |
+#include <netinet/in.h> |
|
30 |
+#include <arpa/nameser.h> |
|
31 |
+#endif |
|
32 |
+#include <resolv.h> |
|
33 |
+#endif |
|
34 |
+ |
|
35 |
+char *dnsquery(const char *domain, int qtype, unsigned int *ttl); |
|
24 | 36 |
|
25 | 37 |
#endif |
... | ... |
@@ -212,7 +212,7 @@ static int wwwconnect(const char *server, const char *proxy, int pport, char *ip |
212 | 212 |
const char *hostpt; |
213 | 213 |
|
214 | 214 |
if(ip) |
215 |
- strcpy(ip, "???"); |
|
215 |
+ strcpy(ip, "UNKNOWN"); |
|
216 | 216 |
|
217 | 217 |
if(proxy) { |
218 | 218 |
hostpt = proxy; |
... | ... |
@@ -1555,13 +1555,21 @@ static int updatedb(const char *dbname, const char *hostname, char *ip, int *sig |
1555 | 1555 |
unsigned int nodb = 0, currver = 0, newver = 0, port = 0, i, j; |
1556 | 1556 |
int ret, ims = -1; |
1557 | 1557 |
char *pt, cvdfile[32], localname[32], *tmpdir = NULL, *newfile, *newfile2, newdb[32]; |
1558 |
- char extradbinfo[64], *extradnsreply = NULL; |
|
1558 |
+ char extradbinfo[64], *extradnsreply = NULL, squery[64]; |
|
1559 | 1559 |
const char *proxy = NULL, *user = NULL, *pass = NULL, *uas = NULL; |
1560 | 1560 |
unsigned int flevel = cl_retflevel(), remote_flevel = 0, maxattempts; |
1561 |
- unsigned int can_whitelist = 0; |
|
1561 |
+ unsigned int can_whitelist = 0, mirror_stats = 0; |
|
1562 |
+#ifdef _WIN32 |
|
1563 |
+ unsigned int w32 = 1; |
|
1564 |
+#else |
|
1565 |
+ unsigned int w32 = 0; |
|
1566 |
+#endif |
|
1562 | 1567 |
int ctimeout, rtimeout; |
1563 | 1568 |
|
1564 | 1569 |
|
1570 |
+ if(cli_strbcasestr(hostname, ".clamav.net")) |
|
1571 |
+ mirror_stats = 1; |
|
1572 |
+ |
|
1565 | 1573 |
snprintf(cvdfile, sizeof(cvdfile), "%s.cvd", dbname); |
1566 | 1574 |
|
1567 | 1575 |
if(!(current = currentdb(dbname, localname))) { |
... | ... |
@@ -1602,7 +1610,7 @@ static int updatedb(const char *dbname, const char *hostname, char *ip, int *sig |
1602 | 1602 |
#ifdef HAVE_RESOLV_H |
1603 | 1603 |
else if(!nodb && extra && !optget(opts, "no-dns")->enabled) { |
1604 | 1604 |
snprintf(extradbinfo, sizeof(extradbinfo), "%s.cvd.clamav.net", dbname); |
1605 |
- if((extradnsreply = txtquery(extradbinfo, NULL))) { |
|
1605 |
+ if((extradnsreply = dnsquery(extradbinfo, T_TXT, NULL))) { |
|
1606 | 1606 |
if((pt = cli_strtok(extradnsreply, 1, ":"))) { |
1607 | 1607 |
int rt; |
1608 | 1608 |
time_t ct; |
... | ... |
@@ -1681,12 +1689,20 @@ static int updatedb(const char *dbname, const char *hostname, char *ip, int *sig |
1681 | 1681 |
if(!nodb && !ims) { |
1682 | 1682 |
logg("%s is up to date (version: %d, sigs: %d, f-level: %d, builder: %s)\n", localname, current->version, current->sigs, current->fl, current->builder); |
1683 | 1683 |
*signo += current->sigs; |
1684 |
+ if(mirror_stats) { |
|
1685 |
+ snprintf(squery, sizeof(squery), "%s.%u.%u.%u.%u.%s.ping.clamav.net", dbname, current->version, flevel, 1, w32, ip); |
|
1686 |
+ dnsquery(squery, T_A, NULL); |
|
1687 |
+ } |
|
1684 | 1688 |
cl_cvdfree(current); |
1685 | 1689 |
return 1; |
1686 | 1690 |
} |
1687 | 1691 |
|
1688 | 1692 |
if(!remote) { |
1689 | 1693 |
logg("^Can't read %s header from %s (IP: %s)\n", cvdfile, hostname, ip); |
1694 |
+ if(mirror_stats) { |
|
1695 |
+ snprintf(squery, sizeof(squery), "%s.%u.%u.%u.%u.%s.ping.clamav.net", dbname, current->version + 1, flevel, 0, w32, ip); |
|
1696 |
+ dnsquery(squery, T_A, NULL); |
|
1697 |
+ } |
|
1690 | 1698 |
cl_cvdfree(current); |
1691 | 1699 |
return 58; |
1692 | 1700 |
} |
... | ... |
@@ -1710,7 +1726,6 @@ static int updatedb(const char *dbname, const char *hostname, char *ip, int *sig |
1710 | 1710 |
return 1; |
1711 | 1711 |
} |
1712 | 1712 |
|
1713 |
- |
|
1714 | 1713 |
if(current) { |
1715 | 1714 |
currver = current->version; |
1716 | 1715 |
cl_cvdfree(current); |
... | ... |
@@ -1741,6 +1756,10 @@ static int updatedb(const char *dbname, const char *hostname, char *ip, int *sig |
1741 | 1741 |
if(nodb) { |
1742 | 1742 |
ret = getcvd(cvdfile, newfile, hostname, ip, localip, proxy, port, user, pass, uas, newver, ctimeout, rtimeout, mdat, logerr, can_whitelist, opts); |
1743 | 1743 |
if(ret) { |
1744 |
+ if(mirror_stats) { |
|
1745 |
+ snprintf(squery, sizeof(squery), "%s.%u.%u.%u.%u.%s.ping.clamav.net", dbname, 0, flevel, 0, w32, ip); |
|
1746 |
+ dnsquery(squery, T_A, NULL); |
|
1747 |
+ } |
|
1744 | 1748 |
memset(ip, 0, 16); |
1745 | 1749 |
free(newfile); |
1746 | 1750 |
return ret; |
... | ... |
@@ -1759,6 +1778,10 @@ static int updatedb(const char *dbname, const char *hostname, char *ip, int *sig |
1759 | 1759 |
llogerr = (j == maxattempts - 1); |
1760 | 1760 |
ret = getpatch(dbname, tmpdir, i, hostname, ip, localip, proxy, port, user, pass, uas, ctimeout, rtimeout, mdat, llogerr, can_whitelist, opts); |
1761 | 1761 |
if(ret == 52 || ret == 58) { |
1762 |
+ if(mirror_stats) { |
|
1763 |
+ snprintf(squery, sizeof(squery), "%s.%u.%u.%u.%u.%s.ping.clamav.net", dbname, i, flevel, 0, w32, ip); |
|
1764 |
+ dnsquery(squery, T_A, NULL); |
|
1765 |
+ } |
|
1762 | 1766 |
memset(ip, 0, 16); |
1763 | 1767 |
continue; |
1764 | 1768 |
} else { |
... | ... |
@@ -1777,6 +1800,10 @@ static int updatedb(const char *dbname, const char *hostname, char *ip, int *sig |
1777 | 1777 |
mirman_whitelist(mdat, 2); |
1778 | 1778 |
ret = getcvd(cvdfile, newfile, hostname, ip, localip, proxy, port, user, pass, uas, newver, ctimeout, rtimeout, mdat, logerr, can_whitelist, opts); |
1779 | 1779 |
if(ret) { |
1780 |
+ if(mirror_stats) { |
|
1781 |
+ snprintf(squery, sizeof(squery), "%s.%u.%u.%u.%u.%s.ping.clamav.net", dbname, 0, flevel, 0, w32, ip); |
|
1782 |
+ dnsquery(squery, T_A, NULL); |
|
1783 |
+ } |
|
1780 | 1784 |
free(newfile); |
1781 | 1785 |
return ret; |
1782 | 1786 |
} |
... | ... |
@@ -1872,6 +1899,10 @@ static int updatedb(const char *dbname, const char *hostname, char *ip, int *sig |
1872 | 1872 |
} |
1873 | 1873 |
|
1874 | 1874 |
*signo += current->sigs; |
1875 |
+ if(mirror_stats) { |
|
1876 |
+ snprintf(squery, sizeof(squery), "%s.%u.%u.%u.%u.%s.ping.clamav.net", dbname, current->version, flevel, 1, w32, ip); |
|
1877 |
+ dnsquery(squery, T_A, NULL); |
|
1878 |
+ } |
|
1875 | 1879 |
cl_cvdfree(current); |
1876 | 1880 |
return 0; |
1877 | 1881 |
} |
... | ... |
@@ -2071,7 +2102,7 @@ int downloadmanager(const struct optstruct *opts, const char *hostname, int loge |
2071 | 2071 |
if(optget(opts, "no-dns")->enabled) { |
2072 | 2072 |
dnsreply = NULL; |
2073 | 2073 |
} else { |
2074 |
- if((dnsreply = txtquery(dnsdbinfo, &ttl))) { |
|
2074 |
+ if((dnsreply = dnsquery(dnsdbinfo, T_TXT, &ttl))) { |
|
2075 | 2075 |
logg("*TTL: %d\n", ttl); |
2076 | 2076 |
|
2077 | 2077 |
if((pt = cli_strtok(dnsreply, 3, ":"))) { |