static void plug_proxy_sent (Plug *p, size_t bufsize) { ProxySocket *ps = container_of(p, ProxySocket, plugimpl); if (ps->state != PROXY_STATE_ACTIVE) { ps->negotiate(ps, PROXY_CHANGE_SENT); return; } plug_sent(ps->plug, bufsize); }
static void plug_proxy_sent (Plug p, int bufsize) { ProxySocket *ps = FROMFIELD(p, ProxySocket, plugvt); if (ps->state != PROXY_STATE_ACTIVE) { ps->sent_bufsize = bufsize; ps->negotiate(ps, PROXY_CHANGE_SENT); return; } plug_sent(ps->plug, bufsize); }
static int plug_proxy_accepting(Plug p, accept_fn_t constructor, accept_ctx_t ctx) { ProxySocket *ps = FROMFIELD(p, ProxySocket, plugvt); if (ps->state != PROXY_STATE_ACTIVE) { ps->accepting_constructor = constructor; ps->accepting_ctx = ctx; return ps->negotiate(ps, PROXY_CHANGE_ACCEPTING); } return plug_accepting(ps->plug, constructor, ctx); }
static void plug_proxy_closing (Plug p, const char *error_msg, int error_code, int calling_back) { ProxySocket *ps = FROMFIELD(p, ProxySocket, plugvt); if (ps->state != PROXY_STATE_ACTIVE) { ps->closing_error_msg = error_msg; ps->closing_error_code = error_code; ps->closing_calling_back = calling_back; ps->negotiate(ps, PROXY_CHANGE_CLOSING); } else { plug_closing(ps->plug, error_msg, error_code, calling_back); } }
static void plug_proxy_receive (Plug p, int urgent, char *data, int len) { ProxySocket *ps = FROMFIELD(p, ProxySocket, plugvt); if (ps->state != PROXY_STATE_ACTIVE) { /* we will lose the urgentness of this data, but since most, * if not all, of this data will be consumed by the negotiation * process, hopefully it won't affect the protocol above us */ bufchain_add(&ps->pending_input_data, data, len); ps->receive_urgent = urgent; ps->receive_data = data; ps->receive_len = len; ps->negotiate(ps, PROXY_CHANGE_RECEIVE); } else { plug_receive(ps->plug, urgent, data, len); } }
Socket new_connection(SockAddr addr, const char *hostname, int port, int privport, int oobinline, int nodelay, int keepalive, Plug plug, Conf *conf) { if (conf_get_int(conf, CONF_proxy_type) != PROXY_NONE && proxy_for_destination(addr, hostname, port, conf)) { ProxySocket *ret; SockAddr proxy_addr; char *proxy_canonical_name; const char *proxy_type; Socket sret; int type; if ((sret = platform_new_connection(addr, hostname, port, privport, oobinline, nodelay, keepalive, plug, conf)) != NULL) return sret; ret = snew(ProxySocket); ret->sockvt = &ProxySocket_sockvt; ret->plugvt = &ProxySocket_plugvt; ret->conf = conf_copy(conf); ret->plug = plug; ret->remote_addr = addr; /* will need to be freed on close */ ret->remote_port = port; ret->error = NULL; ret->pending_flush = 0; ret->pending_eof = 0; ret->freeze = 0; bufchain_init(&ret->pending_input_data); bufchain_init(&ret->pending_output_data); bufchain_init(&ret->pending_oob_output_data); ret->sub_socket = NULL; ret->state = PROXY_STATE_NEW; ret->negotiate = NULL; type = conf_get_int(conf, CONF_proxy_type); if (type == PROXY_HTTP) { ret->negotiate = proxy_http_negotiate; proxy_type = "HTTP"; } else if (type == PROXY_SOCKS4) { ret->negotiate = proxy_socks4_negotiate; proxy_type = "SOCKS 4"; } else if (type == PROXY_SOCKS5) { ret->negotiate = proxy_socks5_negotiate; proxy_type = "SOCKS 5"; } else if (type == PROXY_TELNET) { ret->negotiate = proxy_telnet_negotiate; proxy_type = "Telnet"; } else { ret->error = "Proxy error: Unknown proxy method"; return &ret->sockvt; } { char *logmsg = dupprintf("Will use %s proxy at %s:%d to connect" " to %s:%d", proxy_type, conf_get_str(conf, CONF_proxy_host), conf_get_int(conf, CONF_proxy_port), hostname, port); plug_log(plug, 2, NULL, 0, logmsg, 0); sfree(logmsg); } { char *logmsg = dns_log_msg(conf_get_str(conf, CONF_proxy_host), conf_get_int(conf, CONF_addressfamily), "proxy"); plug_log(plug, 2, NULL, 0, logmsg, 0); sfree(logmsg); } /* look-up proxy */ proxy_addr = sk_namelookup(conf_get_str(conf, CONF_proxy_host), &proxy_canonical_name, conf_get_int(conf, CONF_addressfamily)); if (sk_addr_error(proxy_addr) != NULL) { ret->error = "Proxy error: Unable to resolve proxy host name"; sk_addr_free(proxy_addr); return &ret->sockvt; } sfree(proxy_canonical_name); { char addrbuf[256], *logmsg; sk_getaddr(proxy_addr, addrbuf, lenof(addrbuf)); logmsg = dupprintf("Connecting to %s proxy at %s port %d", proxy_type, addrbuf, conf_get_int(conf, CONF_proxy_port)); plug_log(plug, 2, NULL, 0, logmsg, 0); sfree(logmsg); } /* create the actual socket we will be using, * connected to our proxy server and port. */ ret->sub_socket = sk_new(proxy_addr, conf_get_int(conf, CONF_proxy_port), privport, oobinline, nodelay, keepalive, &ret->plugvt); if (sk_socket_error(ret->sub_socket) != NULL) return &ret->sockvt; /* start the proxy negotiation process... */ sk_set_frozen(ret->sub_socket, 0); ret->negotiate(ret, PROXY_CHANGE_NEW); return &ret->sockvt; } /* no proxy, so just return the direct socket */ return sk_new(addr, port, privport, oobinline, nodelay, keepalive, plug); }