108 static void _dns_result_aaaa(
struct dns_ctx *ctx,
struct dns_rr_a6 *result,
void *data);
109 static void _dns_result_a(
struct dns_ctx *ctx,
struct dns_rr_a4 *result,
void *data);
117 log_debug(
ZONE,
"creating new out packet queue for '%s'", rkey);
131 char *c, *dbkey, *tmp;
134 int from_len, to_len;
139 c = memchr(rkey,
'/', rkeylen);
142 to_len = rkeylen - (c - rkey);
145 tmp = strndup(c, to_len);
158 log_debug(
ZONE,
"sending auth request for %.*s (key %s)", rkeylen, rkey, dbkey);
159 log_write(out->
s2s->
log, LOG_NOTICE,
"[%d] [%s, port=%d] sending dialback auth request for route '%.*s'", out->
fd->
fd, out->
ip, out->
port, rkeylen, rkey);
200 int s_reuse = 0, s_aaaa = 0, s_a = 0, s_bad = 0;
201 int p_reuse = 0, p_aaaa = 0, p_a = 0;
202 int wt_reuse = 0, wt_aaaa = 0, wt_a = 0;
203 int c_expired_good = 0;
236 if (now > res->expiry) {
243 }
else if (bad != NULL && !(now > bad->
expiry)) {
245 l_bad[s_bad++] = res;
251 if (s_reuse == 0 || p_reuse > res->prio) {
256 log_debug(
ZONE,
"reset prio list, using prio %d", res->prio);
258 if (res->prio <= p_reuse) {
259 l_reuse[s_reuse] = res;
261 rw_reuse[s_reuse] = wt_reuse;
264 log_debug(
ZONE,
"added host with weight %d (%d), running weight %d",
265 (res->weight >> 8), res->weight, wt_reuse);
269 }
else if (memchr(ipport,
':', ipport_len) != NULL) {
272 if (s_aaaa == 0 || p_aaaa > res->prio) {
277 log_debug(
ZONE,
"reset prio list, using prio %d", res->prio);
279 if (res->prio <= p_aaaa) {
280 l_aaaa[s_aaaa] = res;
282 rw_aaaa[s_aaaa] = wt_aaaa;
285 log_debug(
ZONE,
"added host with weight %d (%d), running weight %d",
286 (res->weight >> 8), res->weight, wt_aaaa);
293 if (s_a == 0 || p_a > res->prio) {
298 log_debug(
ZONE,
"reset prio list, using prio %d", res->prio);
300 if (res->prio <= p_a) {
306 log_debug(
ZONE,
"added host with weight %d (%d), running weight %d",
307 (res->weight >> 8), res->weight, wt_a);
323 log_debug(
ZONE,
"using existing hosts, total weight %d", wt_reuse);
324 assert((wt_reuse + 1) > 0);
326 r = rand() % (wt_reuse + 1);
329 for (i = 0; i < s_reuse; i++)
330 if (rw_reuse[i] >= r) {
332 l_reuse[i]->key, rw_reuse[i]);
334 ipport = l_reuse[i]->
key;
337 }
else if (s_aaaa > 0 && (s_a == 0 || p_aaaa <= p_a)) {
340 log_debug(
ZONE,
"using IPv6 hosts, total weight %d", wt_aaaa);
341 assert((wt_aaaa + 1) > 0);
343 r = rand() % (wt_aaaa + 1);
346 for (i = 0; i < s_aaaa; i++)
347 if (rw_aaaa[i] >= r) {
349 l_aaaa[i]->key, rw_aaaa[i]);
351 ipport = l_aaaa[i]->
key;
354 }
else if (s_a > 0) {
358 assert((wt_a + 1) > 0);
360 r = rand() % (wt_a + 1);
363 for (i = 0; i < s_a; i++)
366 l_a[i]->key, rw_a[i]);
368 ipport = l_a[i]->
key;
371 }
else if (s_bad > 0) {
372 ipport = l_bad[rand() % s_bad]->
key;
377 if (c_expired_good > 0) {
378 log_debug(
ZONE,
"expiring this DNS cache entry, %d expired hosts",
389 assert(ipport != NULL);
392 ipport_len = strlen(ipport);
393 c = strchr(ipport,
'/');
394 strncpy(ip, ipport, c-ipport);
397 c_len = ipport_len - (c - ipport);
398 tmp = strndup(c, c_len);
412 int port, c_len, from_len;
414 c = memchr(route,
'/', routelen);
415 from_len = c - route;
417 c_len = routelen - (c - route);
418 dkey = strndup(c, c_len);
429 log_debug(
ZONE,
"no dns for %s, preparing for resolution", dkey);
433 strcpy(dns->
name, dkey);
440 strcpy(dns->ip,
"127.0.0.1");
442 dns->
expiry = time(NULL) + 99999999;
468 if (
dns_select(s2s, ip, &port, now, dns, allow_bad)) {
496 log_write(s2s->
log, LOG_NOTICE,
"[%d] [%s, port=%d] using connection for '%s'", (*out)->fd->fd, (*out)->ip, (*out)->port, dkey);
508 (*out)->key = strdup(ipport);
514 strcpy((*out)->ip, ip);
522 (*out)->init_time = time(NULL);
535 if (strchr(ip,
':') != NULL)
540 if ((ip_is_v6 && (strchr(s2s->
origin_ips[i],
':') != NULL)) ||
541 (! ip_is_v6 && (strchr(s2s->
origin_ips[i],
':') == NULL)))
544 if ((*out)->fd != NULL)
break;
547 if ((*out)->fd == NULL) {
567 return out_route(s2s, route, routelen, out, 0);
569 log_write(s2s->
log, LOG_NOTICE,
"[%d] [%s, port=%d] outgoing connection for '%s'", (*out)->fd->fd, (*out)->ip, (*out)->port, dkey);
588 log_debug(
ZONE,
"connection for '%s' found (%d %s/%d)", dkey, (*out)->fd->fd, (*out)->ip, (*out)->port);
592 if (!(*out)->online || reuse) {
593 if (
xhash_getx((*out)->routes, route, routelen) == NULL)
621 log_write(s2s->
log, LOG_NOTICE,
"sending a packet to domain not in the whitelist, dropping it");
624 if (pkt->
from != NULL)
626 if (pkt->
nad != NULL)
635 rkeylen = strlen(rkey);
638 ret =
out_route(s2s, rkey, rkeylen, &out, 1);
729 assert(port > 0 && port < 65536);
731 c = (
char *) malloc(strlen(host) + 7);
732 sprintf(c,
"%s/%d", host, port);
741 if (prio < res->prio)
744 if (prio < res->prio) {
747 }
else if (prio == res->
prio) {
750 if (res->
weight > (65535 << 8))
751 res->
weight = (65535 << 8);
760 log_debug(
ZONE,
"dns result updated for %s@%p: %s (%d/%d/%d)", query->
name, query, ipport,
774 log_debug(
ZONE,
"dns result added for %s@%p: %s (%d/%d/%d)", query->
name, query, ipport,
777 log_debug(
ZONE,
"dns result ignored for %s@%p: %s (%d/%d/%d)", query->
name, query, ipport,
778 prio, (weight >> 8), ttl);
801 if (prio < res->prio)
804 if (prio < res->prio) {
807 }
else if (prio == res->
prio) {
810 if (res->
weight > (65535 << 8))
811 res->
weight = (65535 << 8);
817 log_debug(
ZONE,
"dns host updated for %s@%p: %s (%d/%d/%d)", query->
name, query, ipport,
828 log_debug(
ZONE,
"dns host added for %s@%p: %s (%d/%d/%d)", query->
name, query, ipport,
831 log_debug(
ZONE,
"dns host ignored for %s@%p: %s (%d/%d/%d)", query->
name, query, ipport,
832 prio, (weight >> 8), ttl);
839 static void _dns_result_srv(
struct dns_ctx *ctx,
struct dns_rr_srv *result,
void *data) {
841 assert(query != NULL);
844 if (ctx != NULL && result == NULL) {
847 }
else if (result != NULL) {
851 result->dnssrv_qname, result->dnssrv_nrr, result->dnssrv_ttl);
853 for (i = 0; i < result->dnssrv_nrr; i++) {
854 if (strlen(result->dnssrv_srv[i].name) > 0
855 && result->dnssrv_srv[i].port > 0
856 && result->dnssrv_srv[i].port < 65536) {
858 query, result->dnssrv_qname, i,
859 result->dnssrv_srv[i].
name, result->dnssrv_srv[i].port,
860 result->dnssrv_srv[i].priority, result->dnssrv_srv[i].weight);
863 result->dnssrv_srv[i].port, result->dnssrv_srv[i].priority,
864 result->dnssrv_srv[i].weight, result->dnssrv_ttl);
881 if (query->
query == NULL)
898 query->
query = dns_submit_a6(NULL, query->
name,
902 if (query->
query == NULL)
907 query->
query = dns_submit_a4(NULL, query->
name,
911 if (query->
query == NULL)
922 assert(query != NULL);
925 if (ctx != NULL && result == NULL) {
928 }
else if (result != NULL) {
930 result->dnsa6_qname, result->dnsa6_nrr, result->dnsa6_ttl);
935 for (i = 0; i < result->dnsa6_nrr; i++) {
938 query, result->dnsa6_qname, i, ip, query->
cur_port);
954 if (query->
query == NULL)
958 log_debug(
ZONE,
"dns result for %s@%p: AAAA host vanished...", query->
name, query);
967 #define EHL_LINE_LEN 260
971 char *pcStart, *pcEnd;
979 if ((cszName == NULL) || (szIP == NULL) || (ciMaxIPLen <= 0))
985 pcStart = getenv(
"WINDIR");
986 if (pcStart != NULL) {
987 sprintf(szLine,
"%s\\system32\\drivers\\etc\\hosts", pcStart);
989 strcpy(szLine,
"C:\\WINDOWS\\system32\\drivers\\etc\\hosts");
992 strcpy(szLine,
"/etc/hosts");
994 fHosts = fopen(szLine,
"r");
1001 pcStart = strchr (szLine,
'#');
1002 if (pcStart != NULL)
1004 strcat(szLine,
" ");
1007 iLen = strspn(szLine,
"1234567890.");
1008 if ((iLen < 7) || (iLen > 15))
1010 pcEnd = szLine + iLen;
1015 pcStart = pcEnd + strspn(pcEnd,
" \t\n");
1016 while (*pcStart != 0) {
1017 pcEnd = pcStart + strcspn(pcStart,
" \t\n");
1021 if (strcasecmp(pcStart, cszName) == 0) {
1022 strncpy(szIP, szLine, ciMaxIPLen - 1);
1023 szIP[ciMaxIPLen - 1] =
'\0';
1028 pcStart = pcEnd + strspn(pcEnd,
" \t\n");
1042 static void _dns_result_a(
struct dns_ctx *ctx,
struct dns_rr_a4 *result,
void *data) {
1044 assert(query != NULL);
1045 query->
query = NULL;
1047 if (ctx != NULL && result == NULL) {
1048 #define DRA_IP_LEN 16
1060 }
else if (result != NULL) {
1061 char ip[INET_ADDRSTRLEN];
1065 query, result->dnsa4_qname, result->dnsa4_nrr, result->dnsa4_ttl);
1070 for (i = 0; i < result->dnsa4_nrr; i++) {
1071 if (inet_ntop(AF_INET, &result->dnsa4_addr[i], ip, INET_ADDRSTRLEN) != NULL) {
1073 query, result->dnsa4_qname, i, ip, query->
cur_port);
1085 char *ipport, *c, *tmp;
1086 int ipport_len, ip_len, port_len;
1098 c = memchr(ipport,
'/', ipport_len);
1099 ip_len = c - ipport;
1101 port_len = ipport_len - (c - ipport);
1105 query->
cur_host = strndup(ipport, ip_len);
1106 tmp = strndup(c, port_len);
1120 if (query->
query == NULL)
1128 if (query->
query == NULL)
1134 time_t now = time(NULL);
1173 query->
hosts = NULL;
1174 if (idna_to_unicode_8z8z(query->
name, &domain, 0) != IDNA_SUCCESS) {
1179 query->
expiry = time(NULL) + 99999999;
1180 domain = strdup(query->
name);
1194 if (idna_to_ascii_8z(dns->
name, &query->
name, 0) != IDNA_SUCCESS) {
1197 query->
expiry = time(NULL) + 99999999;
1207 query->
query = NULL;
1236 log_write(s2s->
log, LOG_NOTICE,
"dns lookup for %s failed", domain);
1245 log_write(s2s->
log, LOG_NOTICE,
"dns lookup for %s returned %d result%s (ttl %d)",
1254 if (idna_to_ascii_8z(domain, &punydomain, 0) == IDNA_SUCCESS) {
1261 log_write(s2s->
log, LOG_ERR,
"weird, never requested %s resolution", domain);
1295 ioctl(fd->
fd, FIONREAD, &nbytes);
1335 c = memchr(rkey,
'/', rkeylen);
1337 c_len = rkeylen - (c - rkey);
1341 log_debug(
ZONE,
"removing dest entry for '%.*s'", c_len, c);
1359 log_write(out->
s2s->
log, LOG_NOTICE,
"[%d] [%s, port=%d] retry limit reached for '%.*s' queue", fd->
fd, out->
ip, out->
port, rkeylen, rkey);
1366 log_debug(
ZONE,
"retrying connection for '%.*s' queue", rkeylen, rkey);
1370 if (retry != NULL) {
1428 int len, ns, elem, starttls = 0;
1508 (strstr(sxe->
specific,
"host-gone") ||
1509 strstr(sxe->
specific,
"host-unknown") ||
1510 strstr(sxe->
specific,
"not-authorized") ||
1511 strstr(sxe->
specific,
"see-other-host") ||
1512 strstr(sxe->
specific,
"system-shutdown") ||
1513 strstr(sxe->
specific,
"policy-violation") ||
1514 strstr(sxe->
specific,
"remote-connection-failed") ||
1515 strstr(sxe->
specific,
"unsupported-encoding") ||
1516 strstr(sxe->
specific,
"undefined-condition") ||
1517 strstr(sxe->
specific,
"internal-server-error") ||
1518 strstr(sxe->
specific,
"unsupported-version")
1542 log_debug(
ZONE,
"no stream version, sending dialbacks for %s immediately", out->
key);
1546 log_debug(
ZONE,
"outgoing conn to %s - waiting for STREAM features", out->
key);
1578 log_write(out->
s2s->
log, LOG_ERR,
"unable to establish encrypted session with peer");
1590 log_debug(
ZONE,
"No STARTTLS, dialbacks disabled for non-TLS connections, cannot complete negotiation");
1604 log_debug(
ZONE,
"got a non-dialback packet on an outgoing conn, dropping it");
1611 if(strncmp(
"result",
NAD_ENAME(nad, 0), 6) == 0) {
1616 if(strncmp(
"verify",
NAD_ENAME(nad, 0), 6) == 0) {
1628 if (out->
fd != NULL) {
1647 log_debug(
ZONE,
"missing or invalid from on db result packet");
1654 log_debug(
ZONE,
"missing or invalid to on db result packet");
1661 rkeylen = strlen(rkey);
1665 log_write(out->
s2s->
log, LOG_NOTICE,
"[%d] [%s, port=%d] outgoing route '%s' is now valid%s%s", out->
fd->
fd, out->
ip, out->
port, rkey, (out->
s->
flags &
SX_SSL_WRAPPER) ?
", TLS negotiated" :
"", out->
s->
compressed ?
", ZLIB compression enabled" :
"");
1685 log_write(out->
s2s->
log, LOG_NOTICE,
"[%d] [%s, port=%d] outgoing route '%s' is now invalid", out->
fd->
fd, out->
ip, out->
port, rkey);
1717 log_debug(
ZONE,
"missing or invalid from on db verify packet");
1724 log_debug(
ZONE,
"missing or invalid to on db verify packet");
1754 log_write(in->
s2s->
log, LOG_NOTICE,
"[%d] [%s, port=%d] incoming route '%s' is now valid%s%s", in->
fd->
fd, in->
ip, in->
port, rkey, (in->
s->
flags &
SX_SSL_WRAPPER) ?
", TLS negotiated" :
"", in->
s->
compressed ?
", ZLIB compression enabled" :
"");
1757 log_write(in->
s2s->
log, LOG_NOTICE,
"[%d] [%s, port=%d] incoming route '%s' is now invalid", in->
fd->
fd, in->
ip, in->
port, rkey);
1824 if(pkt->
nad->
ecur > 1 &&
NAD_NURI_L(pkt->
nad,
NAD_ENS(pkt->
nad, 1)) == strlen(
uri_CLIENT) && strncmp(
NAD_NURI(pkt->
nad,
NAD_ENS(pkt->
nad, 1)),
uri_CLIENT, strlen(
uri_CLIENT)) == 0 &&
nad_find_attr(pkt->
nad, 0, -1,
"error", NULL) < 0) {
1837 log_debug(
ZONE,
"deleting out packet queue for %.*s", rkeylen, rkey);
1872 c = memchr(rkey,
'/', rkeylen);
1874 c_len = rkeylen - (c - rkey);
1875 if (strncmp(domain, c, c_len) == 0)
1891 log_debug(
ZONE,
"flushing %d packets for '%.*s' to out_packet", npkt, rkeylen, rkey);
1893 for(i = 0; i < npkt; i++) {
1908 log_debug(
ZONE,
"deleting out packet queue for '%.*s'", rkeylen, rkey);