Beispiel #1
0
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;
}
Beispiel #2
0
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);
        }
    }
}
Beispiel #3
0
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);
	}
}
Beispiel #4
0
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);
    }
}
Beispiel #5
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);
}
Beispiel #6
0
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);
    }
}
Beispiel #7
0
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);
}
Beispiel #8
0
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);
    }
}