/* 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,
* 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
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;
}
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 *
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);
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] = {
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;
}
}
}
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;
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);
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);
}
}
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;
}
}
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;
}
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;
}
}
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);
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);
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;
}
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;
}
}
}
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;
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);
}
{
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);
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;
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;
}
}
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;
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)
}
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);
}
/* 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);
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);
- }
+ }
}
}