Browse code

freshclam: add mirror statistics mechanism

Tomasz Kojm authored on 2011/04/27 22:09:05
Showing 4 changed files
... ...
@@ -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, ":"))) {