static int localproxy_select_result(int fd, int event) { Local_Proxy_Socket s; char buf[20480]; int ret; if (!(s = find234(localproxy_by_fromfd, &fd, localproxy_fromfd_find)) && !(s = find234(localproxy_by_tofd, &fd, localproxy_tofd_find)) ) return 1; /* boggle */ if (event == 1) { assert(fd == s->from_cmd); ret = read(fd, buf, sizeof(buf)); if (ret < 0) { return plug_closing(s->plug, strerror(errno), errno, 0); } else if (ret == 0) { return plug_closing(s->plug, NULL, 0, 0); } else { return plug_receive(s->plug, 0, buf, ret); } } else if (event == 2) { assert(fd == s->to_cmd); if (localproxy_try_send(s)) plug_sent(s->plug, bufchain_size(&s->pending_output_data)); return 1; } return 1; }
static int handle_gotdata(struct handle *h, void *data, int len) { Handle_Socket ps = (Handle_Socket) handle_get_privdata(h); if (len < 0) { return plug_closing(ps->plug, "Read error from handle", 0, 0); } else if (len == 0) { return plug_closing(ps->plug, NULL, 0, 0); } else { assert(ps->frozen != FREEZING && ps->frozen != THAWING); if (ps->frozen == FREEZING) { /* * If we've received data while this socket is supposed to * be frozen (because the read winhandl.c started before * sk_set_frozen was called has now returned) then buffer * the data for when we unfreeze. */ bufchain_add(&ps->inputdata, data, len); /* * And return a very large backlog, to prevent further * data arriving from winhandl until we unfreeze. */ return INT_MAX; } else { return plug_receive(ps->plug, 0, data, len); } } }
int localproxy_gotdata(struct handle *h, void *data, int len) { Local_Proxy_Socket ps = (Local_Proxy_Socket) handle_get_privdata(h); if (len < 0) { return plug_closing(ps->plug, "Read error from local proxy command", 0, 0); } else if (len == 0) { return plug_closing(ps->plug, NULL, 0, 0); } else { return plug_receive(ps->plug, 1, data, len); } }
static void handle_socket_unfreeze(void *psv) { Handle_Socket ps = (Handle_Socket) psv; void *data; int len; /* * If we've been put into a state other than THAWING since the * last callback, then we're done. */ if (ps->frozen != THAWING) return; /* * Get some of the data we've buffered. */ bufchain_prefix(&ps->inputdata, &data, &len); assert(len > 0); /* * Hand it off to the plug. Be careful of re-entrance - that might * have the effect of trying to close this socket. */ ps->defer_close = TRUE; plug_receive(ps->plug, 0, data, len); bufchain_consume(&ps->inputdata, len); ps->defer_close = FALSE; if (ps->deferred_close) { sk_handle_close(ps); return; } if (bufchain_size(&ps->inputdata) > 0) { /* * If there's still data in our buffer, stay in THAWING state, * and reschedule ourself. */ queue_toplevel_callback(handle_socket_unfreeze, ps); } else { /* * Otherwise, we've successfully thawed! */ ps->frozen = UNFROZEN; handle_unthrottle(ps->recv_h, 0); } }
static int plug_proxy_receive(Plug p, int urgent, byte *data, int len) { Proxy_Plug pp = (Proxy_Plug) p; Proxy_Socket ps = pp->proxy_socket; 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; return ps->negotiate(ps, PROXY_CHANGE_RECEIVE); } return plug_receive(ps->plug, urgent, data, len); }
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); } }
static void sk_proxy_set_frozen(Socket s, int is_frozen) { Proxy_Socket ps = (Proxy_Socket)s; if (ps->state != PROXY_STATE_ACTIVE) { ps->freeze = is_frozen; return; } /* handle any remaining buffered recv data first */ if (bufchain_size(&ps->pending_input_data) > 0) { ps->freeze = is_frozen; /* loop while we still have buffered data, and while we are * unfrozen. the plug_receive call in the loop could result * in a call back into this function refreezing the socket, * so we have to check each time. */ while (!ps->freeze && bufchain_size(&ps->pending_input_data) > 0) { void *data; char databuf[512]; int len; bufchain_prefix(&ps->pending_input_data, &data, &len); if (len > lenof(databuf)) len = lenof(databuf); memcpy(databuf, data, len); bufchain_consume(&ps->pending_input_data, len); plug_receive(ps->plug, 0, databuf, len); } /* if we're still frozen, we'll have to wait for another * call from the backend to finish unbuffering the data. */ if (ps->freeze) return; } sk_set_frozen(ps->sub_socket, is_frozen); }
static void handle_socket_unfreeze(void *psv) { Handle_Socket ps = (Handle_Socket) psv; void *data; int len, new_backlog; /* * If we've been put into a state other than THAWING since the * last callback, then we're done. */ if (ps->frozen != THAWING) return; /* * Get some of the data we've buffered. */ bufchain_prefix(&ps->inputdata, &data, &len); assert(len > 0); /* * Hand it off to the plug. */ new_backlog = plug_receive(ps->plug, 0, data, len); if (bufchain_size(&ps->inputdata) > 0) { /* * If there's still data in our buffer, stay in THAWING state, * and reschedule ourself. */ queue_toplevel_callback(handle_socket_unfreeze, ps); } else { /* * Otherwise, we've successfully thawed! */ ps->frozen = UNFROZEN; handle_unthrottle(ps->recv_h, new_backlog); } }