/** Address to hostname lookup wrapper */ struct evdns_request * evdns_getnameinfo(struct evdns_base *base, const struct sockaddr *addr, int flags, evdns_callback_type callback, void *data) { if (addr->sa_family == AF_INET) { const struct sockaddr_in *a = (const struct sockaddr_in *) addr; #if SSL_DEBUG_LEVEL > 1 errputs(stdout, "Remote connection is IPv4."); #endif return evdns_base_resolve_reverse(base, &a->sin_addr, flags, callback, data); } else if (addr->sa_family == AF_INET6) { const struct sockaddr_in6 *a = (const struct sockaddr_in6 *) addr; #if SSL_DEBUG_LEVEL > 1 errputs(stdout, "Remote connection is IPv6."); #endif return evdns_base_resolve_reverse_ipv6(base, &a->sin6_addr, flags, callback, data); } else { errprintf(stdout, "ssl_slave: Attempt to resolve unknown socket family %d\n", addr->sa_family); return NULL; } }
/** Read from one buffer and write the results to the other */ void pipe_cb(struct bufferevent *from_bev, void *data) { struct conn *c = data; char buff[BUFFER_LEN]; size_t len; struct bufferevent *to_bev = NULL; if (c->local_bev == from_bev) { #if SSL_DEBUG_LEVEL > 1 errputs(stdout, "got data from mush."); #endif to_bev = c->remote_bev; } else { #if SSL_DEBUG_LEVEL > 1 errputs(stdout, "got data from SSL"); #endif to_bev = c->local_bev; } len = bufferevent_read(from_bev, buff, sizeof buff); #if SSL_DEBUG_LEVEL > 1 errprintf(stdout, "ssl_slave: read %zu bytes.\n", len); #endif if (to_bev && len > 0) { if (bufferevent_write(to_bev, buff, len) < 0) errputs(stderr, "write failed!"); } }
bool scontextEncode(scontext *sc, int sym) /** returns flag "coded by me or not" **/ { if ( sc->tree[sym] == 0 ) { #ifdef DEBUG if ( sc->escape == 0 || sc->nzero < 1 ) { errputs("stats: cannot code zero-probability novel symbol"); fprintf(stderr,"sym: %d , esc: %d, nzero: %d\n",sym,sc->escape,sc->nzero); exit(1); } #endif arithEncode(sc->arith, sc->total, sc->total+sc->escape, sc->total+sc->escape); scontextAdd(sc,sym); return false; } else { int low, high, i; low=0; for(i=0;i<sym;i++) low += sc->tree[i]; high = low + sc->tree[sym]; arithEncode(sc->arith,low, high, sc->total+sc->escape); scontextAdd(sc,sym); } return true; }
/** Called after the local connection to the mush has established */ void local_connected(struct conn *c) { char *hostid; int len; #if SSL_DEBUG_LEVEL > 0 errputs(stdout, "Local connection attempt completed. Setting up pipe."); #endif bufferevent_setcb(c->local_bev, pipe_cb, NULL, ssl_event_cb, c); bufferevent_enable(c->local_bev, EV_READ | EV_WRITE); bufferevent_setcb(c->remote_bev, pipe_cb, NULL, ssl_event_cb, c); bufferevent_enable(c->remote_bev, EV_READ | EV_WRITE); c->state = C_ESTABLISHED; /* Now pass the remote host and IP to the mush as the very first line it gets */ len = strlen(c->remote_host) + strlen(c->remote_ip) + 3; hostid = malloc(len + 1); sprintf(hostid, "%s^%s\r\n", c->remote_ip, c->remote_host); if (send_with_creds(bufferevent_getfd(c->local_bev), hostid, len) < 0) { penn_perror("send_with_creds"); delete_conn(c); } free(hostid); }
/** Called after the SSL connection and initial handshaking is complete. */ void ssl_connected(struct conn *c) { X509 *peer; SSL *ssl; #if SSL_DEBUG_LEVEL > 0 errputs(stdout, "SSL connection attempt completed. Resolving remote host name."); errprintf(stdout, "ssl_slave: ssl error code: %ld\n", bufferevent_get_openssl_error(c->remote_bev)); #endif bufferevent_set_timeouts(c->remote_bev, NULL, NULL); ssl = bufferevent_openssl_get_ssl(c->remote_bev); /* Successful accept. Log peer certificate, if any. */ if ((peer = SSL_get_peer_certificate(ssl))) { if (SSL_get_verify_result(ssl) == X509_V_OK) { char buf[256]; /* The client sent a certificate which verified OK */ X509_NAME_oneline(X509_get_subject_name(peer), buf, 256); errprintf(stdout, "SSL client certificate accepted: %s\n", buf); } } c->state = C_HOSTNAME_LOOKUP; c->resolver_req = evdns_getnameinfo(resolver, &c->remote_addr.addr, 0, address_resolved, c); }