git-svn: trunk@3981
aCaB authored on 2008/07/24 05:14:28... | ... |
@@ -1,3 +1,7 @@ |
1 |
+Wed Jul 23 21:53:10 CEST 2008 (acab) |
|
2 |
+------------------------------------ |
|
3 |
+ * clamav-milter: use thread safe resolv calls - bb#668 |
|
4 |
+ |
|
1 | 5 |
Wed Jul 23 16:32:32 EEST 2008 (edwin) |
2 | 6 |
------------------------------------ |
3 | 7 |
* libclamav: performance improvements for URL matching (bb #725, bb #650): |
... | ... |
@@ -591,6 +591,39 @@ static int useful_header(const char *cmd); |
591 | 591 |
|
592 | 592 |
extern short logg_foreground; |
593 | 593 |
|
594 |
+ |
|
595 |
+res_state res_pool; |
|
596 |
+uint8_t *res_pool_state; |
|
597 |
+ |
|
598 |
+pthread_cond_t res_pool_cond = PTHREAD_COND_INITIALIZER; |
|
599 |
+pthread_mutex_t res_pool_mutex = PTHREAD_MUTEX_INITIALIZER; |
|
600 |
+ |
|
601 |
+int safe_res_query(const char *d, int c, int t, u_char *a, int l) { |
|
602 |
+ int i = -1, ret; |
|
603 |
+ |
|
604 |
+ pthread_mutex_lock(&res_pool_mutex); |
|
605 |
+ while(i==-1) { |
|
606 |
+ int j; |
|
607 |
+ for(j=0; j<max_children+1; j++) { |
|
608 |
+ if(!res_pool_state[j]) continue; |
|
609 |
+ i = j; |
|
610 |
+ break; |
|
611 |
+ } |
|
612 |
+ if(i!=-1) break; |
|
613 |
+ pthread_cond_wait(&res_pool_cond, &res_pool_mutex); |
|
614 |
+ } |
|
615 |
+ res_pool_state[i]=0; |
|
616 |
+ pthread_mutex_unlock(&res_pool_mutex); |
|
617 |
+ |
|
618 |
+ ret = res_nquery(&res_pool[i], d, c, t, a, l); |
|
619 |
+ |
|
620 |
+ pthread_mutex_lock(&res_pool_mutex); |
|
621 |
+ res_pool_state[i]=1; |
|
622 |
+ pthread_cond_signal(&res_pool_cond); |
|
623 |
+ pthread_mutex_unlock(&res_pool_mutex); |
|
624 |
+ return ret; |
|
625 |
+} |
|
626 |
+ |
|
594 | 627 |
static void |
595 | 628 |
help(void) |
596 | 629 |
{ |
... | ... |
@@ -1362,6 +1395,15 @@ main(int argc, char **argv) |
1362 | 1362 |
if((max_children == 0) && ((cpt = cfgopt(copt, "MaxThreads")) != NULL)) |
1363 | 1363 |
max_children = cfgopt(copt, "MaxThreads")->numarg; |
1364 | 1364 |
|
1365 |
+ /* allocate a pool of resolvers */ |
|
1366 |
+ if(!(res_pool=cli_calloc(max_children+1, sizeof(*res_pool)))) |
|
1367 |
+ return EX_OSERR; |
|
1368 |
+ if(!(res_pool_state=cli_malloc(max_children+1))) |
|
1369 |
+ return EX_OSERR; |
|
1370 |
+ memset(res_pool_state, 1, max_children+1); |
|
1371 |
+ for(i = 0; i < max_children+1; i++) |
|
1372 |
+ res_ninit(&res_pool[i]); |
|
1373 |
+ |
|
1365 | 1374 |
if((cpt = cfgopt(copt, "ReadTimeout")) != NULL) { |
1366 | 1375 |
readTimeout = cpt->numarg; |
1367 | 1376 |
|
... | ... |
@@ -6190,7 +6232,7 @@ mx(const char *host, table_t *t) |
6190 | 6190 |
return NULL; |
6191 | 6191 |
} |
6192 | 6192 |
|
6193 |
- len = res_query(host, C_IN, T_MX, (u_char *)&q, sizeof(q)); |
|
6193 |
+ len = safe_res_query(host, C_IN, T_MX, (u_char *)&q, sizeof(q)); |
|
6194 | 6194 |
if(len < 0) |
6195 | 6195 |
return t; /* Host has no MX records */ |
6196 | 6196 |
|
... | ... |
@@ -6259,7 +6301,7 @@ resolve(const char *host, table_t *t) |
6259 | 6259 |
if((host == NULL) || (*host == '\0')) |
6260 | 6260 |
return t; |
6261 | 6261 |
|
6262 |
- len = res_query(host, C_IN, T_A, (u_char *)&q, sizeof(q)); |
|
6262 |
+ len = safe_res_query(host, C_IN, T_A, (u_char *)&q, sizeof(q)); |
|
6263 | 6263 |
if(len < 0) |
6264 | 6264 |
return t; /* Host has no A records */ |
6265 | 6265 |
|
... | ... |
@@ -6318,7 +6360,6 @@ resolve(const char *host, table_t *t) |
6318 | 6318 |
* an SPF system, we ONLY use SPF records to reduce phish false positives |
6319 | 6319 |
* TODO: IPv6? |
6320 | 6320 |
* TODO: cache queries? |
6321 |
- * TODO: check res_query is thread safe |
|
6322 | 6321 |
* |
6323 | 6322 |
* INPUT: prevhosts, a list of hosts already searched: stops include loops |
6324 | 6323 |
* e.g. mercado.com includes medrcadosw.com which includes mercado.com, |
... | ... |
@@ -6370,7 +6411,7 @@ spf(struct privdata *privdata, table_t *prevhosts) |
6370 | 6370 |
*ptr = '\0'; |
6371 | 6371 |
|
6372 | 6372 |
logg("*SPF query '%s'\n", host); |
6373 |
- len = res_query(host, C_IN, T_TXT, (u_char *)&q, sizeof(q)); |
|
6373 |
+ len = safe_res_query(host, C_IN, T_TXT, (u_char *)&q, sizeof(q)); |
|
6374 | 6374 |
if(len < 0) { |
6375 | 6375 |
free(host); |
6376 | 6376 |
return 0; /* Host has no TXT records */ |