/** Called after the remote hostname has been resolved. */ void address_resolved(int result, char type, int count, int ttl __attribute__ ((__unused__)), void *addresses, void *data) { struct conn *c = data; struct sockaddr_un addr; struct hostname_info *ipaddr; c->resolver_req = NULL; if (result == DNS_ERR_CANCEL) { /* Called on a connection that gets dropped while still doing the hostname lookup */ return; } if (result != DNS_ERR_NONE || !addresses || type != DNS_PTR || count == 0) { ipaddr = ip_convert(&c->remote_addr.addr, c->remote_addrlen); c->remote_host = strdup(ipaddr->hostname); c->remote_ip = strdup(ipaddr->hostname); } else { const char *hostname = ((const char **) addresses)[0]; c->remote_host = strdup(hostname); ipaddr = ip_convert(&c->remote_addr.addr, c->remote_addrlen); c->remote_ip = strdup(ipaddr->hostname); } #if SSL_DEBUG_LEVEL > 0 errprintf(stdout, "ssl_slave: resolved hostname as '%s(%s)'. Opening local connection to mush.\n", c->remote_host, c->remote_ip); #endif c->state = C_LOCAL_CONNECTING; addr.sun_family = AF_LOCAL; strncpy(addr.sun_path, socket_file, sizeof(addr.sun_path) - 1); c->local_bev = bufferevent_socket_new(main_loop, -1, BEV_OPT_CLOSE_ON_FREE | BEV_OPT_DEFER_CALLBACKS); bufferevent_socket_connect(c->local_bev, (struct sockaddr *) &addr, sizeof addr); bufferevent_setcb(c->local_bev, NULL, NULL, ssl_event_cb, data); bufferevent_enable(c->local_bev, EV_WRITE); }
void query_info_slave(int fd) { struct request_dgram req; struct hostname_info *hi; char buf[BUFFER_LEN], *bp; ssize_t slen; FD_SET(fd, &info_pending); if (fd > pending_max) pending_max = fd + 1; info_queue_time = time(NULL); if (info_slave_state == INFO_SLAVE_DOWN) { if (!make_info_slave()) { FD_CLR(fd, &info_pending); closesocket(fd); /* Just drop the connection if the slave gets halted. A subsequent reconnect will work. */ } return; } memset(&req, 0, sizeof req); req.rlen = MAXSOCKADDR; if (getpeername(fd, (struct sockaddr *) req.remote.data, &req.rlen) < 0) { penn_perror("socket peer vanished"); shutdown(fd, 2); closesocket(fd); FD_CLR(fd, &info_pending); return; } /* Check for forbidden sites before bothering with ident */ bp = buf; hi = ip_convert(&req.remote.addr, req.rlen); safe_str(hi ? hi->hostname : "Not found", buf, &bp); *bp = '\0'; if (Forbidden_Site(buf)) { char port[NI_MAXSERV]; if (getnameinfo(&req.remote.addr, req.rlen, NULL, 0, port, sizeof port, NI_NUMERICHOST | NI_NUMERICSERV) != 0) penn_perror("getting remote port number"); else { if (!Deny_Silent_Site(buf, AMBIGUOUS)) { do_log(LT_CONN, 0, 0, "[%d/%s] Refused connection (remote port %s)", fd, buf, port); } } closesocket(fd); FD_CLR(fd, &info_pending); return; } req.llen = MAXSOCKADDR; if (getsockname(fd, (struct sockaddr *) req.local.data, &req.llen) < 0) { penn_perror("socket self vanished"); closesocket(fd); FD_CLR(fd, &info_pending); return; } req.fd = fd; req.use_dns = USE_DNS; slen = send(info_slave, &req, sizeof req, 0); if (slen < 0) { penn_perror("info slave query: write error"); make_info_slave(); return; } else if (slen != (int) sizeof req) { /* Shouldn't happen! */ penn_perror("info slave query: partial packet"); make_info_slave(); return; } info_slave_state = INFO_SLAVE_PENDING; }