]> jfr.im git - irc/evilnet/x3.git/blobdiff - src/mod-sockcheck.c
Couple of srvx updates.
[irc/evilnet/x3.git] / src / mod-sockcheck.c
index dfefff34d7d570f40d5a43da874db21638c0deb7..1ba86fb36c222087c29bd24d7f10d33e5359ac0f 100644 (file)
@@ -1,11 +1,11 @@
 /* mod-sockcheck.c - insecure proxy checking
- * Copyright 2000-2006 srvx Development Team
+ * Copyright 2000-2004 srvx Development Team
  *
- * This file is part of srvx.
+ * This file is part of x3.
  *
- * srvx is free software; you can redistribute it and/or modify
+ * x3 is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 3 of the License, or
  * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
@@ -75,7 +75,7 @@ static dict_t checked_ip_dict;
  * state and the input).  Mealy state machines require fewer states to
  * match the same input than Moore machines (where the output is only
  * a function of the current state).
- *
+ * 
  * A state is characterized by sending some data (possibly nothing),
  * waiting a certain amount of time to receive one of zero or more
  * responses, and a decision (accept, reject, continue to another
@@ -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,8 @@ 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, 0);
+    gline_add("ProxyCheck", addr, sockcheck_conf.gline_duration, sci->reason, now, 1, 1);
+
 }
 
 static struct sockcheck_client *
@@ -227,7 +228,7 @@ 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);
     ioset_close(client->fd, 1);
@@ -260,14 +261,14 @@ sockcheck_print_client(const struct sockcheck_client *client)
     log_module(PC_LOG, LOG_INFO, "client %p: { addr = %p { decision = %s; last_touched = "FMT_TIME_T"; 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] = {
@@ -298,29 +299,29 @@ expand_var(const struct sockcheck_client *client, char var, char **p_expansion,
         break;
     case 'i':
         exp4 = client->addr->addr.in6_32[3];
-        exp_length = sizeof(exp4);
-        expansion = (char*)&exp4;
-        break;
+       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;
     }
 }
 
@@ -402,11 +403,11 @@ sockcheck_elaborate_state(struct sockcheck_client *client)
     }
     for (nn=0; nn<client->state->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;
@@ -429,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; (n<tests->used) && (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);
@@ -477,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; n<client->read_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; n<client->read_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);
     }
 
@@ -509,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;
     }
 }
@@ -527,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; n<client->read_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; n<client->read_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;
             }
@@ -601,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;
     }
 }
 
@@ -671,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);
@@ -691,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);
@@ -772,29 +773,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;
 }
@@ -821,7 +822,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;
     }
@@ -841,29 +842,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; n<new_test->responses.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;
@@ -876,14 +877,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);
 }
@@ -893,12 +894,12 @@ sockcheck_free_state(struct sockcheck_state *state)
 {
     unsigned int n;
     if (state->type == CHECKING) {
-        for (n=0; n<state->responses.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; n<state->responses.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);
@@ -916,8 +917,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;
@@ -925,7 +926,7 @@ sockcheck_add_test(const char *desc)
 }
 
 static void
-sockcheck_shutdown(void)
+sockcheck_shutdown(UNUSED_ARG(void *extra))
 {
     unsigned int n;
 
@@ -940,12 +941,12 @@ sockcheck_shutdown(void)
     dict_delete(checked_ip_dict);
     sci_list_clean(&pending_sci_list);
     if (tests)
-        for (n=0; n<tests->used; n++)
-            sockcheck_free_state(tests->list[n]);
+       for (n=0; n<tests->used; 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;
     }
 }
 
@@ -1001,8 +1002,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;
@@ -1015,7 +1016,7 @@ static MODCMD_FUNC(cmd_hostscan)
     char hnamebuf[IRC_NTOP_MAX_SIZE];
 
     for (n=1; n<argc; n++) {
-        struct userNode *un = GetUserH(argv[n]);
+       struct userNode *un = GetUserH(argv[n]);
 
         if (un) {
             if (!irc_in_addr_is_valid(un->ip)
@@ -1056,10 +1057,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);
@@ -1097,7 +1098,7 @@ static MODCMD_FUNC(cmd_stats_proxycheck)
 }
 
 static int
-sockcheck_new_user(struct userNode *user) {
+sockcheck_new_user(struct userNode *user, UNUSED_ARG(void *extra)) {
     /* 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)
@@ -1137,19 +1138,21 @@ 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, "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);
@@ -1158,7 +1161,7 @@ sockcheck_read_conf(void)
             sockcheck_conf.local_addr = NULL;
             if (str)
                 log_module(PC_LOG, LOG_ERROR, "Error: Unable to get host named `%s', not checking from a specific address.", str);
-        }
+       }
     }
 }
 
@@ -1167,7 +1170,7 @@ sockcheck_init(void)
 {
     PC_LOG = log_register_type("ProxyCheck", "file:proxycheck.log");
     conf_register_reload(sockcheck_read_conf);
-    reg_exit_func(sockcheck_shutdown);
+    reg_exit_func(sockcheck_shutdown, NULL);
     _sockcheck_init();
     message_register_table(msgtab);
 
@@ -1176,7 +1179,7 @@ sockcheck_init(void)
     modcmd_register(sockcheck_module, "hostscan", cmd_hostscan, 2, 0, "level", "650", NULL);
     modcmd_register(sockcheck_module, "clearhost", cmd_clearhost, 2, 0, "level", "650", NULL);
     modcmd_register(sockcheck_module, "stats proxycheck", cmd_stats_proxycheck, 0, 0, NULL);
-    reg_new_user_func(sockcheck_new_user);
+    reg_new_user_func(sockcheck_new_user, NULL);
     return 1;
 }