Beispiel #1
0
//---------------------------------------------------------------------
// 尽可能的接收数据
//---------------------------------------------------------------------
int apr_recvall(int sock, void *buf, long size)
{
	unsigned char *lptr = (unsigned char*)buf;
	int total = 0, retval = 0, c;

	for (; size > 0; lptr += retval, size -= (long)retval) {
		retval = apr_recv(sock, lptr, size, 0);
		if (retval == 0) {
			retval = -1;
			break;
		}
		if (retval == -1) {
			c = apr_errno();
			if (c != IEAGAIN) {
				retval = -1000 - c;
				break;
			}
			retval = 0;
			break;
		}
		total += retval;
	}

	return (retval < 0)? retval : total;
}
Beispiel #2
0
static apr_status_t
fill_input_buffer (apr_socket_t * socket)
{
  input_buffer_t * buffer;
  apr_size_t length;

  RELAY_ERROR (get_input_buffer (socket, (&buffer)));
#if (HAVE_APR_1_2_2)
  RELAY_ERROR
    (((length = (sizeof (buffer->data))),
      (apr_socket_recv (socket, (buffer->data), (&length)))));
#else
   RELAY_ERROR
     (((length = (sizeof (buffer->data))),
       (apr_recv (socket, (buffer->data), (&length)))));
#endif
  (buffer->start) = (buffer->data);
  (buffer->end) = ((buffer->data) + length);
  if (length == 0)
    (buffer->start) += 1;
  return (APR_SUCCESS);
}
Beispiel #3
0
static apr_status_t rfc1413_query(apr_socket_t *sock, conn_rec *conn, 
                                  server_rec *srv)
{
    apr_port_t rmt_port, our_port;
    apr_port_t sav_rmt_port, sav_our_port;
    apr_size_t i;
    char *cp;
    char buffer[RFC1413_MAXDATA + 1];
    char user[RFC1413_USERLEN + 1];	/* XXX */
    apr_size_t buflen;

    apr_sockaddr_port_get(&sav_our_port, conn->local_addr);
    apr_sockaddr_port_get(&sav_rmt_port, conn->remote_addr);

    /* send the data */
    buflen = apr_snprintf(buffer, sizeof(buffer), "%hu,%hu\r\n", sav_rmt_port,
                          sav_our_port);
    ap_xlate_proto_to_ascii(buffer, buflen);

    /* send query to server. Handle short write. */
    i = 0;
    while (i < buflen) {
        apr_size_t j = strlen(buffer + i);
        apr_status_t status;
	status  = apr_send(sock, buffer+i, &j);
	if (status != APR_SUCCESS) {
	    ap_log_error(APLOG_MARK, APLOG_CRIT, status, srv,
		         "write: rfc1413: error sending request");
	    return status;
	}
	else if (j > 0) {
	    i+=j; 
	}
    }

    /*
     * Read response from server. - the response should be newline 
     * terminated according to rfc - make sure it doesn't stomp its
     * way out of the buffer.
     */

    i = 0;
    memset(buffer, '\0', sizeof(buffer));
    /*
     * Note that the strchr function below checks for \012 instead of '\n'
     * this allows it to work on both ASCII and EBCDIC machines.
     */
    while((cp = strchr(buffer, '\012')) == NULL && i < sizeof(buffer) - 1) {
        apr_size_t j = sizeof(buffer) - 1 - i;
        apr_status_t status;
	status = apr_recv(sock, buffer+i, &j);
	if (status != APR_SUCCESS) {
	    ap_log_error(APLOG_MARK, APLOG_CRIT, status, srv,
			"read: rfc1413: error reading response");
	    return status;
	}
	else if (j > 0) {
	    i+=j; 
	}
        else if (status == APR_SUCCESS && j == 0) {
            /* Oops... we ran out of data before finding newline */
            return APR_EINVAL;
        }
    }

/* RFC1413_USERLEN = 512 */
    ap_xlate_proto_from_ascii(buffer, i);
    if (sscanf(buffer, "%hu , %hu : USERID :%*[^:]:%512s", &rmt_port, &our_port,
	       user) != 3 || sav_rmt_port != rmt_port
	|| sav_our_port != our_port)
	return APR_EINVAL;

    /*
     * Strip trailing carriage return. It is part of the
     * protocol, not part of the data.
     */

    if ((cp = strchr(user, '\r')))
	*cp = '\0';

    conn->remote_logname = apr_pstrdup(conn->pool, user);

    return APR_SUCCESS;
}
Beispiel #4
0
AP_DECLARE(void) ap_lingering_close(conn_rec *c)
{
    char dummybuf[512];
    apr_size_t nbytes = sizeof(dummybuf);
    apr_status_t rc;
    apr_int32_t timeout;
    apr_int32_t total_linger_time = 0;
    apr_socket_t *csd = ap_get_module_config(c->conn_config, &core_module);

    if (!csd) {
        return;
    }

    ap_update_child_status(c->sbh, SERVER_CLOSING, NULL);

#ifdef NO_LINGCLOSE
    ap_flush_conn(c); /* just close it */
    apr_socket_close(csd);
    return;
#endif

    /* Close the connection, being careful to send out whatever is still
     * in our buffers.  If possible, try to avoid a hard close until the
     * client has ACKed our FIN and/or has stopped sending us data.
     */

    /* Send any leftover data to the client, but never try to again */
    ap_flush_conn(c);

    if (c->aborted) {
        apr_socket_close(csd);
        return;
    }

    /* Shut down the socket for write, which will send a FIN
     * to the peer.
     */
    if (apr_shutdown(csd, APR_SHUTDOWN_WRITE) != APR_SUCCESS
        || c->aborted) {
        apr_socket_close(csd);
        return;
    }

    /* Read all data from the peer until we reach "end-of-file" (FIN
     * from peer) or we've exceeded our overall timeout. If the client does
     * not send us bytes within 2 seconds (a value pulled from Apache 1.3
     * which seems to work well), close the connection.
     */
    timeout = apr_time_from_sec(SECONDS_TO_LINGER);
    apr_socket_timeout_set(csd, timeout);
    apr_socket_opt_set(csd, APR_INCOMPLETE_READ, 1);
    while (1) {
        nbytes = sizeof(dummybuf);
        rc = apr_recv(csd, dummybuf, &nbytes);
        if (rc != APR_SUCCESS || nbytes == 0)
            break;

        total_linger_time += SECONDS_TO_LINGER;
        if (total_linger_time >= MAX_SECS_TO_LINGER) {
            break;
        }
    }

    apr_socket_close(csd);
    return;
}