X-Git-Url: http://git.pk910.de/?a=blobdiff_plain;f=src%2Fmod-sockcheck.c;h=ab68da07cd558aed9f41112bd544617eee4cd928;hb=HEAD;hp=08ce625e14b65a527d43943e00c7a99d8376542e;hpb=eab92374e96aaa3faae341d4a0b8cc3fd0102ebd;p=srvx.git diff --git a/src/mod-sockcheck.c b/src/mod-sockcheck.c index 08ce625..ab68da0 100644 --- a/src/mod-sockcheck.c +++ b/src/mod-sockcheck.c @@ -1,5 +1,5 @@ /* mod-sockcheck.c - insecure proxy checking - * Copyright 2000-2004 srvx Development Team + * Copyright 2000-2006 srvx Development Team * * This file is part of srvx. * @@ -53,7 +53,7 @@ enum sockcheck_decision { typedef struct { irc_in_addr_t addr; const char *reason; - time_t last_touched; + unsigned long last_touched; enum sockcheck_decision decision; char hostname[IRC_NTOP_MAX_SIZE]; /* acts as key for checked_ip_dict */ } *sockcheck_cache_info; @@ -152,7 +152,7 @@ static const struct message_entry msgtab[] = { { "PCMSG_DISABLED", "Proxy scanning is $bdisabled$b." }, { "PCMSG_NOT_CACHED", "No proxycheck records exist for IP %s." }, { "PCMSG_STATUS_CHECKING", "IP %s proxycheck state: last touched %s ago, still checking" }, - { "PCMSG_STATUS_ACCEPTED", "IP %s proxycheck state: last touched %s ago, acepted" }, + { "PCMSG_STATUS_ACCEPTED", "IP %s proxycheck state: last touched %s ago, accepted" }, { "PCMSG_STATUS_REJECTED", "IP %s proxycheck state: last touched %s ago, rejected: %s" }, { "PCMSG_STATUS_UNKNOWN", "IP %s proxycheck state: last touched %s ago, invalid status" }, { "PCMSG_STATISTICS", "Since booting, I have checked %d clients for illicit proxies, and detected %d proxy hosts.\nI am currently checking %d clients (out of %d max) and have a backlog of %d more to start on.\nI currently have %d hosts cached.\nI know how to detect %d kinds of proxies." }, @@ -174,8 +174,8 @@ static void sockcheck_list_append(struct sockcheck_list *list, struct sockcheck_state *new_item) { if (list->used == list->size) { - list->size <<= 1; - list->list = realloc(list->list, list->size*sizeof(list->list[0])); + list->size <<= 1; + list->list = realloc(list->list, list->size*sizeof(list->list[0])); } list->list[list->used++] = new_item; } @@ -206,7 +206,7 @@ sockcheck_issue_gline(sockcheck_cache_info sci) char addr[IRC_NTOP_MAX_SIZE + 2] = {'*', '@', '\0'}; irc_ntop(addr + 2, sizeof(addr) - 2, &sci->addr); log_module(PC_LOG, LOG_INFO, "Issuing gline for client at %s: %s", addr + 2, sci->reason); - gline_add("ProxyCheck", addr, sockcheck_conf.gline_duration, sci->reason, now, now, 1); + gline_add("ProxyCheck", addr, sockcheck_conf.gline_duration, sci->reason, now, now, 0, 1); } static struct sockcheck_client * @@ -227,11 +227,11 @@ static void sockcheck_free_client(struct sockcheck_client *client) { if (SOCKCHECK_DEBUG) { - log_module(PC_LOG, LOG_INFO, "Goodbye %s (%p)! I set you free!", client->addr->hostname, client); + log_module(PC_LOG, LOG_INFO, "Goodbye %s (%p)! I set you free!", client->addr->hostname, (void*)client); } verify(client); - if (client->fd) - ioset_close(client->fd->fd, 1); + ioset_close(client->fd, 1); + client->fd = NULL; sockcheck_list_unref(client->tests); free(client->read); free(client->resp_state); @@ -257,17 +257,18 @@ static void sockcheck_print_client(const struct sockcheck_client *client) { static const char *decs[] = {"CHECKING", "ACCEPT", "REJECT"}; - log_module(PC_LOG, LOG_INFO, "client %p: { addr = %p { decision = %s; last_touched = "FMT_TIME_T"; reason = %s; hostname = \"%s\" }; " + log_module(PC_LOG, LOG_INFO, "client %p: { addr = %p { decision = %s; last_touched = %lu; reason = %s; hostname = \"%s\" }; " "test_index = %d; state = %p { port = %d; type = %s; template = \"%s\"; ... }; " "fd = %p(%d); read = %p; read_size = %d; read_used = %d; read_pos = %d; }", - client, client->addr, decs[client->addr->decision], client->addr->last_touched, + (void*)client, (void*)client->addr, decs[client->addr->decision], + client->addr->last_touched, client->addr->reason, client->addr->hostname, - client->test_index, client->state, + client->test_index, (void*)client->state, (client->state ? client->state->port : 0), (client->state ? decs[client->state->type] : "N/A"), (client->state ? client->state->template : "N/A"), - client->fd, (client->fd ? client->fd->fd : 0), - client->read, client->read_size, client->read_used, client->read_pos); + (void*)client->fd, (client->fd ? client->fd->fd : 0), + (void*)client->read, client->read_size, client->read_used, client->read_pos); } static char hexvals[256] = { @@ -287,13 +288,9 @@ expand_var(const struct sockcheck_client *client, char var, char **p_expansion, extern struct cManagerNode cManager; const char *expansion; unsigned int exp_length; -#ifndef __SOLARIS__ - u_int32_t exp4; - u_int16_t exp2; -#else uint32_t exp4; uint16_t exp2; -#endif + /* expand variable */ switch (var) { case 'c': @@ -301,30 +298,30 @@ expand_var(const struct sockcheck_client *client, char var, char **p_expansion, exp_length = strlen(expansion); break; case 'i': - exp4 = client->addr->addr.in6_32[3]; - exp_length = sizeof(exp4); - expansion = (char*)&exp4; - break; + exp4 = client->addr->addr.in6_32[3]; + exp_length = sizeof(exp4); + expansion = (char*)&exp4; + break; case 'p': - exp2 = htons(client->state->port); - exp_length = sizeof(exp2); - expansion = (char*)&exp2; - break; + exp2 = htons(client->state->port); + exp_length = sizeof(exp2); + expansion = (char*)&exp2; + break; case 'u': - expansion = cManager.uplink->host; - exp_length = strlen(expansion); - break; + expansion = cManager.uplink->host; + exp_length = strlen(expansion); + break; default: log_module(PC_LOG, LOG_WARNING, "Request to expand unknown sockcheck variable $%c, using empty expansion.", var); - expansion = ""; - exp_length = 0; + expansion = ""; + exp_length = 0; } if (p_expansion) { - *p_expansion = malloc(exp_length); - memcpy(*p_expansion, expansion, exp_length); + *p_expansion = malloc(exp_length); + memcpy(*p_expansion, expansion, exp_length); } if (p_exp_length) { - *p_exp_length = exp_length; + *p_exp_length = exp_length; } } @@ -406,11 +403,11 @@ sockcheck_elaborate_state(struct sockcheck_client *client) } for (nn=0; nnstate->responses.used; nn++) { /* Set their resp_state to the start of the response. */ - client->resp_state[nn] = client->state->responses.list[nn]->template; + client->resp_state[nn] = client->state->responses.list[nn]->template; /* If it doesn't require reading, take it now. */ if (client->resp_state[nn] && !*client->resp_state[nn]) { if (SOCKCHECK_DEBUG) { - log_module(PC_LOG, LOG_INFO, "Skipping straight to easy option %d for %p.", nn, client); + log_module(PC_LOG, LOG_INFO, "Skipping straight to easy option %d for %p.", nn, (void*)client); } sockcheck_advance(client, nn); return; @@ -433,32 +430,32 @@ sockcheck_decide(struct sockcheck_client *client, enum sockcheck_decision decisi client->addr->last_touched = now; switch (decision) { case ACCEPT: - /* do nothing */ + /* do nothing */ if (SOCKCHECK_DEBUG) { log_module(PC_LOG, LOG_INFO, "Proxy check passed for client at %s.", client->addr->hostname); } break; case REJECT: - client->addr->reason = client->state->template; - proxies_detected++; - sockcheck_issue_gline(client->addr); + client->addr->reason = client->state->template; + proxies_detected++; + sockcheck_issue_gline(client->addr); if (SOCKCHECK_DEBUG) { log_module(PC_LOG, LOG_INFO, "Proxy check rejects client at %s (%s)", client->addr->hostname, client->addr->reason); } - /* Don't compare test_index != 0 directly, because somebody - * else may have reordered the tests already. */ - if (client->tests->list[client->test_index] != tests->list[0]) { - struct sockcheck_list *new_tests = sockcheck_list_clone(tests); - struct sockcheck_state *new_first = client->tests->list[client->test_index]; + /* Don't compare test_index != 0 directly, because somebody + * else may have reordered the tests already. */ + if (client->tests->list[client->test_index] != tests->list[0]) { + struct sockcheck_list *new_tests = sockcheck_list_clone(tests); + struct sockcheck_state *new_first = client->tests->list[client->test_index]; for (n=0; (nused) && (tests->list[n] != new_first); n++) ; for (; n>0; n--) new_tests->list[n] = new_tests->list[n-1]; - new_tests->list[0] = new_first; - sockcheck_list_unref(tests); - tests = new_tests; - } + new_tests->list[0] = new_first; + sockcheck_list_unref(tests); + tests = new_tests; + } break; default: - log_module(PC_LOG, LOG_ERROR, "BUG: sockcheck_decide(\"%s\", %d): unrecognized decision.", client->addr->hostname, decision); + log_module(PC_LOG, LOG_ERROR, "BUG: sockcheck_decide(\"%s\", %d): unrecognized decision.", client->addr->hostname, decision); } n = client->client_index; sockcheck_free_client(client); @@ -481,16 +478,16 @@ sockcheck_advance(struct sockcheck_client *client, unsigned int next_state) unsigned int n, m; char buffer[201]; static const char *hexmap = "0123456789ABCDEF"; - log_module(PC_LOG, LOG_INFO, "sockcheck_advance(%s) following response %d (type %d) of %d.", client->addr->hostname, next_state, client->state->responses.list[next_state]->next->type, client->state->responses.used); - for (n=0; nread_used; n++) { - for (m=0; (m<(sizeof(buffer)-1)>>1) && ((n+m) < client->read_used); m++) { - buffer[m << 1] = hexmap[client->read[n+m] >> 4]; - buffer[m << 1 | 1] = hexmap[client->read[n+m] & 15]; - } - buffer[m<<1] = 0; - log_module(PC_LOG, LOG_INFO, " .. read data: %s", buffer); - n += m; - } + log_module(PC_LOG, LOG_INFO, "sockcheck_advance(%s) following response %d (type %d) of %d.", client->addr->hostname, next_state, client->state->responses.list[next_state]->next->type, client->state->responses.used); + for (n=0; nread_used; n++) { + for (m=0; (m<(sizeof(buffer)-1)>>1) && ((n+m) < client->read_used); m++) { + buffer[m << 1] = hexmap[client->read[n+m] >> 4]; + buffer[m << 1 | 1] = hexmap[client->read[n+m] & 15]; + } + buffer[m<<1] = 0; + log_module(PC_LOG, LOG_INFO, " .. read data: %s", buffer); + n += m; + } sockcheck_print_client(client); } @@ -513,7 +510,7 @@ sockcheck_advance(struct sockcheck_client *client, unsigned int next_state) } break; default: - log_module(PC_LOG, LOG_ERROR, "BUG: unknown next-state type %d (after %p).", ns->type, client->state); + log_module(PC_LOG, LOG_ERROR, "BUG: unknown next-state type %d (after %p).", ns->type, (void*)client->state); break; } } @@ -531,66 +528,66 @@ sockcheck_readable(struct io_fd *fd) if (res < 0) { switch (res = errno) { default: - log_module(PC_LOG, LOG_ERROR, "BUG: sockcheck_readable(%d/%s): read() returned errno %d (%s)", fd->fd, client->addr->hostname, errno, strerror(errno)); + log_module(PC_LOG, LOG_ERROR, "BUG: sockcheck_readable(%d/%s): read() returned errno %d (%s)", fd->fd, client->addr->hostname, errno, strerror(errno)); case EAGAIN: return; case ECONNRESET: sockcheck_advance(client, client->state->responses.used - 1); return; - } + } } else if (res == 0) { sockcheck_advance(client, client->state->responses.used - 1); return; } else { - client->read_used += res; + client->read_used += res; } if (SOCKCHECK_DEBUG) { unsigned int n, m; char buffer[201]; static const char *hexmap = "0123456789ABCDEF"; - for (n=0; nread_used; n++) { - for (m=0; (m<(sizeof(buffer)-1)>>1) && ((n+m) < client->read_used); m++) { - buffer[m << 1] = hexmap[client->read[n+m] >> 4]; - buffer[m << 1 | 1] = hexmap[client->read[n+m] & 15]; - } - buffer[m<<1] = 0; - log_module(PC_LOG, LOG_INFO, "read %d bytes data: %s", client->read_used, buffer); - n += m; - } + for (n=0; nread_used; n++) { + for (m=0; (m<(sizeof(buffer)-1)>>1) && ((n+m) < client->read_used); m++) { + buffer[m << 1] = hexmap[client->read[n+m] >> 4]; + buffer[m << 1 | 1] = hexmap[client->read[n+m] & 15]; + } + buffer[m<<1] = 0; + log_module(PC_LOG, LOG_INFO, "read %d bytes data: %s", client->read_used, buffer); + n += m; + } } /* See if what's been read matches any of the expected responses */ while (client->read_pos < client->read_used) { unsigned int last_pos = client->read_pos; - char bleh; - const char *resp_state; + char bleh; + const char *resp_state; - for (nn=0; nn<(client->state->responses.used-1); nn++) { + for (nn=0; nn<(client->state->responses.used-1); nn++) { char *expected; unsigned int exp_length = 1, free_exp = 0; - /* compare against possible target */ - resp_state = client->resp_state[nn]; - if (resp_state == NULL) continue; - switch (*resp_state) { - case '=': + /* compare against possible target */ + resp_state = client->resp_state[nn]; + if (resp_state == NULL) continue; + switch (*resp_state) { + case '=': bleh = resp_state[1]; expected = &bleh; break; - case '.': + case '.': /* any character passes */ client->read_pos++; exp_length = 0; break; - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': - case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': - bleh = hexvals[(unsigned char)resp_state[0]] << 4 + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + bleh = hexvals[(unsigned char)resp_state[0]] << 4 | hexvals[(unsigned char)resp_state[1]]; expected = &bleh; - break; - case '$': - expand_var(client, resp_state[1], &expected, &exp_length); + break; + case '$': + expand_var(client, resp_state[1], &expected, &exp_length); free_exp = 1; break; } @@ -605,27 +602,27 @@ sockcheck_readable(struct io_fd *fd) resp_state -= 2; } if (free_exp) free(expected); - if (resp_state) { - client->resp_state[nn] = resp_state = resp_state + 2; - if (!*resp_state) { + if (resp_state) { + client->resp_state[nn] = resp_state = resp_state + 2; + if (!*resp_state) { sockcheck_advance(client, nn); - return; - } - } else { - client->resp_state[nn] = NULL; - } - } + return; + } + } else { + client->resp_state[nn] = NULL; + } + } if (last_pos == client->read_pos) break; } /* nothing seemed to match. what now? */ if (client->read_used >= client->read_size) { - /* we got more data than we expected to get .. don't read any more */ + /* we got more data than we expected to get .. don't read any more */ if (SOCKCHECK_DEBUG) { log_module(PC_LOG, LOG_INFO, "Buffer filled (unmatched) for client %s", client->addr->hostname); } sockcheck_advance(client, client->state->responses.used-1); - return; + return; } } @@ -648,7 +645,6 @@ sockcheck_connected(struct io_fd *fd, int rc) return; case 0: break; } - fd->wants_reads = 1; if (SOCKCHECK_DEBUG) { log_module(PC_LOG, LOG_INFO, "Connected: to %s port %d.", client->addr->hostname, client->state->port); } @@ -661,15 +657,14 @@ sockcheck_begin_test(struct sockcheck_client *client) struct io_fd *io_fd; verify(client); - if (client->fd) { - ioset_close(client->fd->fd, 1); - client->fd = NULL; - } + ioset_close(client->fd, 1); + client->fd = NULL; do { client->state = client->tests->list[client->test_index]; client->read_pos = 0; client->read_used = 0; - client->fd = io_fd = ioset_connect(sockcheck_conf.local_addr, sockcheck_conf.local_addr_len, client->addr->hostname, client->state->port, 0, client, sockcheck_connected); + io_fd = ioset_connect(sockcheck_conf.local_addr, sockcheck_conf.local_addr_len, client->addr->hostname, client->state->port, 0, client, sockcheck_connected); + client->fd = io_fd; if (!io_fd) { client->test_index++; continue; @@ -677,7 +672,7 @@ sockcheck_begin_test(struct sockcheck_client *client) io_fd->readable_cb = sockcheck_readable; timeq_add(now + client->state->timeout, sockcheck_timeout_client, client); if (SOCKCHECK_DEBUG) { - log_module(PC_LOG, LOG_INFO, "Starting proxy check on %s:%d (test %d) with fd %d (%p).", client->addr->hostname, client->state->port, client->test_index, io_fd->fd, io_fd); + log_module(PC_LOG, LOG_INFO, "Starting proxy check on %s:%d (test %d) with fd %d (%p).", client->addr->hostname, client->state->port, client->test_index, io_fd->fd, (void*)io_fd); } return; } while (client->test_index < client->tests->used); @@ -697,11 +692,11 @@ sockcheck_start_client(unsigned int idx) return; } memmove(pending_sci_list.list, pending_sci_list.list+1, - (--pending_sci_list.used)*sizeof(pending_sci_list.list[0])); + (--pending_sci_list.used)*sizeof(pending_sci_list.list[0])); sockcheck_num_clients++; if (!tests) return; client = client_list[idx] = sockcheck_alloc_client(sci); - log_module(PC_LOG, LOG_INFO, "Proxy-checking client at %s as client %d (%p) of %d.", sci->hostname, idx, client, sockcheck_num_clients); + log_module(PC_LOG, LOG_INFO, "Proxy-checking client at %s as client %d (%p) of %d.", sci->hostname, idx, (void*)client, sockcheck_num_clients); client->test_rep = 0; client->client_index = idx; sockcheck_begin_test(client); @@ -721,10 +716,12 @@ sockcheck_queue_address(irc_in_addr_t addr) /* We are already checking this host. */ return; case ACCEPT: - if ((sci->last_touched + sockcheck_conf.max_cache_age) >= (unsigned)now) return; + if (sci->last_touched + sockcheck_conf.max_cache_age >= now) { + return; + } break; case REJECT: - if ((sci->last_touched + sockcheck_conf.gline_duration) >= (unsigned)now) { + if (sci->last_touched + sockcheck_conf.gline_duration >= now) { sockcheck_issue_gline(sci); return; } @@ -778,29 +775,29 @@ sockcheck_create_response(const char *key, void *data, void *extra) response_list_append(&parent->responses, resp); /* now figure out how to create resp->next */ if ((str = GET_RECORD_QSTRING(rd))) { - if (!ircncasecmp(str, "reject", 6)) { - resp->next->type = REJECT; - } else if (!ircncasecmp(str, "accept", 6)) { - resp->next->type = ACCEPT; - } else { - log_module(PC_LOG, LOG_ERROR, "Error: unknown sockcheck decision `%s', defaulting to accept.", str); - resp->next->type = ACCEPT; - } - if (str[6]) { - resp->next->template = strdup(str+7); - } else { - resp->next->template = strdup("No explanation given"); - } + if (!ircncasecmp(str, "reject", 6)) { + resp->next->type = REJECT; + } else if (!ircncasecmp(str, "accept", 6)) { + resp->next->type = ACCEPT; + } else { + log_module(PC_LOG, LOG_ERROR, "Error: unknown sockcheck decision `%s', defaulting to accept.", str); + resp->next->type = ACCEPT; + } + if (str[6]) { + resp->next->template = strdup(str+7); + } else { + resp->next->template = strdup("No explanation given"); + } } else if ((resps = GET_RECORD_OBJECT(rd))) { - resp->next->type = CHECKING; - response_list_init(&resp->next->responses); - if (*end == ':') { - resp->next->template = strdup(end+1); + resp->next->type = CHECKING; + response_list_init(&resp->next->responses); + if (*end == ':') { + resp->next->template = strdup(end+1); if (!sockcheck_check_template(resp->next->template, 0)) _exit(1); - } else { - resp->next->template = strdup(""); - } - dict_foreach(resps, sockcheck_create_response, resp->next); + } else { + resp->next->template = strdup(""); + } + dict_foreach(resps, sockcheck_create_response, resp->next); } return 0; } @@ -827,7 +824,7 @@ sockcheck_create_test(const char *key, void *data, void *extra) new_test->type = CHECKING; response_list_init(&new_test->responses); if (!(object = GET_RECORD_OBJECT(rd))) { - log_module(PC_LOG, LOG_ERROR, "Error: misformed sockcheck test `%s', skipping it.", key); + log_module(PC_LOG, LOG_ERROR, "Error: misformed sockcheck test `%s', skipping it.", key); free(new_test); return 1; } @@ -847,29 +844,29 @@ sockcheck_create_test(const char *key, void *data, void *extra) } } if (!new_test->template) { - log_module(PC_LOG, LOG_ERROR, "Error: misformed sockcheck test `%s', skipping it.", key); - free(new_test); - return 1; + log_module(PC_LOG, LOG_ERROR, "Error: misformed sockcheck test `%s', skipping it.", key); + free(new_test); + return 1; } dict_foreach(object, sockcheck_create_response, new_test); /* If none of the responses have template "other", create a * default response that goes to accept. */ for (n=0; nresponses.used; n++) { - if (!strcmp(new_test->responses.list[n]->template, "other")) break; + if (!strcmp(new_test->responses.list[n]->template, "other")) break; } if (n == new_test->responses.used) { - rd = alloc_record_data_qstring("accept"); - sockcheck_create_response("other", rd, new_test); - free_record_data(rd); + rd = alloc_record_data_qstring("accept"); + sockcheck_create_response("other", rd, new_test); + free_record_data(rd); } else if (n != (new_test->responses.used - 1)) { - struct sockcheck_response *tmp; - /* switch the response for "other" to the end */ - tmp = new_test->responses.list[new_test->responses.used - 1]; - new_test->responses.list[new_test->responses.used - 1] = new_test->responses.list[n]; - new_test->responses.list[n] = tmp; + struct sockcheck_response *tmp; + /* switch the response for "other" to the end */ + tmp = new_test->responses.list[new_test->responses.used - 1]; + new_test->responses.list[new_test->responses.used - 1] = new_test->responses.list[n]; + new_test->responses.list[n] = tmp; } if (new_test->responses.used > max_responses) { - max_responses = new_test->responses.used; + max_responses = new_test->responses.used; } sockcheck_list_append(extra, new_test); return 0; @@ -882,14 +879,14 @@ sockcheck_read_tests(void) struct sockcheck_list *new_tests; test_db = parse_database(SOCKCHECK_TEST_DB); if (!test_db) - return; + return; if (dict_size(test_db) > 0) { - new_tests = sockcheck_list_alloc(dict_size(test_db)); - dict_foreach(test_db, sockcheck_create_test, new_tests); - if (tests) sockcheck_list_unref(tests); - tests = new_tests; + new_tests = sockcheck_list_alloc(dict_size(test_db)); + dict_foreach(test_db, sockcheck_create_test, new_tests); + if (tests) sockcheck_list_unref(tests); + tests = new_tests; } else { - log_module(PC_LOG, LOG_ERROR, "%s was empty - disabling sockcheck.", SOCKCHECK_TEST_DB); + log_module(PC_LOG, LOG_ERROR, "%s was empty - disabling sockcheck.", SOCKCHECK_TEST_DB); } free_database(test_db); } @@ -899,12 +896,12 @@ sockcheck_free_state(struct sockcheck_state *state) { unsigned int n; if (state->type == CHECKING) { - for (n=0; nresponses.used; n++) { - free((char*)state->responses.list[n]->template); - sockcheck_free_state(state->responses.list[n]->next); - free(state->responses.list[n]); - } - response_list_clean(&state->responses); + for (n=0; nresponses.used; n++) { + free((char*)state->responses.list[n]->template); + sockcheck_free_state(state->responses.list[n]->next); + free(state->responses.list[n]); + } + response_list_clean(&state->responses); } free((char*)state->template); free(state); @@ -922,8 +919,8 @@ sockcheck_add_test(const char *desc) return reason; new_tests = sockcheck_list_clone(tests); if (sockcheck_create_test(name, rd, new_tests)) { - sockcheck_list_unref(new_tests); - return "Sockcheck test parse error"; + sockcheck_list_unref(new_tests); + return "Sockcheck test parse error"; } sockcheck_list_unref(tests); tests = new_tests; @@ -946,12 +943,12 @@ sockcheck_shutdown(void) dict_delete(checked_ip_dict); sci_list_clean(&pending_sci_list); if (tests) - for (n=0; nused; n++) - sockcheck_free_state(tests->list[n]); + for (n=0; nused; n++) + sockcheck_free_state(tests->list[n]); sockcheck_list_unref(tests); if (sockcheck_conf.local_addr) { - free(sockcheck_conf.local_addr); - sockcheck_conf.local_addr_len = 0; + free(sockcheck_conf.local_addr); + sockcheck_conf.local_addr_len = 0; } } @@ -976,7 +973,7 @@ sockcheck_clean_cache(UNUSED_ARG(void *data)) string_buffer_append_string(&sb, client_list[nn]->addr->hostname); } string_buffer_append(&sb, '\0'); - log_module(PC_LOG, LOG_INFO, "Cleaning sockcheck cache at "FMT_TIME_T"; current clients: %s.", now, sb.list); + log_module(PC_LOG, LOG_INFO, "Cleaning sockcheck cache at %lu; current clients: %s.", (unsigned long)now, sb.list); string_buffer_clean(&sb); } else { for (curr_clients = dict_new(), nn=0; nn < sockcheck_conf.max_clients; nn++) { @@ -993,7 +990,7 @@ sockcheck_clean_cache(UNUSED_ARG(void *data)) if (((sci->last_touched + max_age) < now) && !dict_find(curr_clients, sci->hostname, NULL)) { if (SOCKCHECK_DEBUG) { - log_module(PC_LOG, LOG_INFO, " .. nuking %s (last touched "FMT_TIME_T").", sci->hostname, sci->last_touched); + log_module(PC_LOG, LOG_INFO, " .. nuking %s (last touched %lu).", sci->hostname, sci->last_touched); } dict_remove(checked_ip_dict, sci->hostname); } @@ -1007,8 +1004,8 @@ static MODCMD_FUNC(cmd_defproxy) const char *reason; if ((reason = sockcheck_add_test(unsplit_string(argv+1, argc-1, NULL)))) { - reply("PCMSG_PROXY_DEFINITION_FAILED", reason); - return 0; + reply("PCMSG_PROXY_DEFINITION_FAILED", reason); + return 0; } reply("PCMSG_PROXY_DEFINITION_SUCCEEDED"); return 1; @@ -1021,7 +1018,7 @@ static MODCMD_FUNC(cmd_hostscan) char hnamebuf[IRC_NTOP_MAX_SIZE]; for (n=1; nip) @@ -1034,7 +1031,7 @@ static MODCMD_FUNC(cmd_hostscan) } } else { char *scanhost = argv[n]; - if (!irc_pton(&ipaddr, NULL, scanhost)) { + if (irc_pton(&ipaddr, NULL, scanhost)) { sockcheck_queue_address(ipaddr); reply("PCMSG_ADDRESS_QUEUED", scanhost); } else { @@ -1062,10 +1059,10 @@ static MODCMD_FUNC(cmd_clearhost) } switch (sockcheck_uncache_host(scanhost)) { case -1: - reply("PCMSG_CHECKING_ADDRESS", scanhost); + reply("PCMSG_CHECKING_ADDRESS", scanhost); break; case 0: - reply("PCMSG_NOT_REMOVED_FROM_CACHE", scanhost); + reply("PCMSG_NOT_REMOVED_FROM_CACHE", scanhost); break; default: reply("PCMSG_REMOVED_FROM_CACHE", scanhost); @@ -1102,14 +1099,13 @@ static MODCMD_FUNC(cmd_stats_proxycheck) } } -static int +static void sockcheck_new_user(struct userNode *user) { /* If they have a bum IP, or are bursting in, don't proxy-check or G-line them. */ if (irc_in_addr_is_valid(user->ip) && !irc_in_addr_is_loopback(user->ip) && !user->uplink->burst) sockcheck_queue_address(user->ip); - return 0; } static void @@ -1143,26 +1139,29 @@ sockcheck_read_conf(void) } /* now try to read from the conf database */ if ((my_node = conf_get_data("modules/sockcheck", RECDB_OBJECT))) { - str = database_get_data(my_node, "max_sockets", RECDB_QSTRING); - if (str) sockcheck_conf.max_clients = strtoul(str, NULL, 0); - str = database_get_data(my_node, "max_clients", RECDB_QSTRING); - if (str) sockcheck_conf.max_clients = strtoul(str, NULL, 0); - str = database_get_data(my_node, "max_read", RECDB_QSTRING); - if (str) sockcheck_conf.max_read = strtoul(str, NULL, 0); - str = database_get_data(my_node, "max_cache_age", RECDB_QSTRING); - if (str) sockcheck_conf.max_cache_age = ParseInterval(str); + str = database_get_data(my_node, "max_sockets", RECDB_QSTRING); + if (str) sockcheck_conf.max_clients = strtoul(str, NULL, 0); + str = database_get_data(my_node, "max_clients", RECDB_QSTRING); + if (str) sockcheck_conf.max_clients = strtoul(str, NULL, 0); + str = database_get_data(my_node, "max_read", RECDB_QSTRING); + if (str) sockcheck_conf.max_read = strtoul(str, NULL, 0); + str = database_get_data(my_node, "max_cache_age", RECDB_QSTRING); + if (str) sockcheck_conf.max_cache_age = ParseInterval(str); str = database_get_data(my_node, "gline_duration", RECDB_QSTRING); if (str) sockcheck_conf.gline_duration = ParseInterval(str); - str = database_get_data(my_node, "address", RECDB_QSTRING); + str = database_get_data(my_node, "bind_address", RECDB_QSTRING); + if (!str) str = database_get_data(my_node, "address", RECDB_QSTRING); if (!getaddrinfo(str, NULL, NULL, &ai)) { - sockcheck_conf.local_addr_len = ai->ai_addrlen; + sockcheck_conf.local_addr_len = ai->ai_addrlen; sockcheck_conf.local_addr = calloc(1, ai->ai_addrlen); memcpy(sockcheck_conf.local_addr, ai->ai_addr, ai->ai_addrlen); + freeaddrinfo(ai); } else { sockcheck_conf.local_addr_len = 0; sockcheck_conf.local_addr = NULL; - log_module(PC_LOG, LOG_ERROR, "Error: Unable to get host named `%s', not checking a specific address.", str); - } + if (str) + log_module(PC_LOG, LOG_ERROR, "Error: Unable to get host named `%s', not checking from a specific address.", str); + } } }