Example #1
0
apr_status_t stomp_disconnect(stomp_connection **connection_ref)
{
   apr_status_t result, rc;
	stomp_connection *connection = *connection_ref;
   
	btlogger_trace("stomp_disconnect");
   if( connection_ref == NULL || *connection_ref==NULL ) {
      btlogger_warn("stomp_disconnect no connection_ref APR_EGENERAL");
      return APR_EGENERAL;
   }
   
	result = APR_SUCCESS;	
   rc = apr_socket_shutdown(connection->socket, APR_SHUTDOWN_WRITE);	
	if( result!=APR_SUCCESS )
		result = rc;
   
   if( connection->socket != NULL ) {
      btlogger_debug("from stomp.c (2) closing socket");
      rc = apr_socket_close(connection->socket);
      if( result!=APR_SUCCESS )
         result = rc;
      connection->socket=NULL;
   }   
	*connection_ref=NULL;
	return rc;	
}
Example #2
0
/********************************************************************************
 * 
 * Used to establish a connection
 *
 ********************************************************************************/
apr_status_t stomp_connect(stomp_connection **connection_ref, const char *hostname, int port, apr_pool_t *pool)
{
	apr_status_t rc;
	int socket_family;
	stomp_connection *connection=NULL;
   
	btlogger_trace("stomp_connect");
	//
	// Allocate the connection and a memory pool for the connection.
	//
	connection = apr_pcalloc(pool, sizeof(stomp_connection));
	if( connection == NULL ) {
		btlogger_warn("stomp_connect cannot allocate for pool APR_ENOMEM");
		return APR_ENOMEM;
	}
   
#define CHECK_SUCCESS if( rc!=APR_SUCCESS ) { return rc; }
   
	// Look up the remote address
	rc = apr_sockaddr_info_get(&connection->remote_sa, hostname, APR_INET, port, 0, pool);
	CHECK_SUCCESS;
	
	// Create and Connect the socket.
	socket_family = connection->remote_sa->sa.sin.sin_family;
	rc = apr_socket_create(&connection->socket, socket_family, SOCK_STREAM, APR_PROTO_TCP, pool);
	CHECK_SUCCESS;	
   rc = apr_socket_connect(connection->socket, connection->remote_sa);
//	CHECK_SUCCESS;
   if( rc != APR_SUCCESS ) {
		apr_status_t rc2 = apr_socket_shutdown(connection->socket, APR_SHUTDOWN_WRITE);
		btlogger_debug("from stomp.c (1) closing socket");
		rc2 = apr_socket_close(connection->socket);
		return rc;
	}
   
   // Get the Socket Info
   rc = apr_socket_addr_get(&connection->remote_sa, APR_REMOTE, connection->socket);
	CHECK_SUCCESS;
//   rc = apr_sockaddr_ip_get(&connection->remote_ip, connection->remote_sa);
//	CHECK_SUCCESS;
   connection->remote_ip = connection->remote_sa->hostname;
   rc = apr_socket_addr_get(&connection->local_sa, APR_LOCAL, connection->socket);
	CHECK_SUCCESS;
   rc = apr_sockaddr_ip_get(&connection->local_ip, connection->local_sa);
	CHECK_SUCCESS;	
   
   // Set socket options.
   //	rc = apr_socket_timeout_set( connection->socket, 2*APR_USEC_PER_SEC);
   //	CHECK_SUCCESS;
   
#undef CHECK_SUCCESS
   
	*connection_ref = connection;
	return rc;	
}
Example #3
0
static int socket_shutdown(lua_State *L)
{
  const char *options[] = { "read", "write", "both", NULL };
  const apr_shutdown_how_e values[] = {
    APR_SHUTDOWN_READ, APR_SHUTDOWN_WRITE, APR_SHUTDOWN_READWRITE
  };
  lua_apr_socket *socket;
  apr_status_t status;
  apr_shutdown_how_e how;

  socket = socket_check(L, 1, 1);
  how = values[luaL_checkoption(L, 2, NULL, options)];
  status = apr_socket_shutdown(socket->handle, how);

  return push_status(L, status);
}
Example #4
0
APR_DECLARE(apr_status_t) stomp_disconnect(stomp_connection **connection_ref)
{
   apr_status_t result, rc;
	stomp_connection *connection = *connection_ref;
   
   if( connection_ref == NULL || *connection_ref==NULL )
      return APR_EGENERAL;
   
	result = APR_SUCCESS;	
   rc = apr_socket_shutdown(connection->socket, APR_SHUTDOWN_WRITE);	
	if( result!=APR_SUCCESS )
		result = rc;
   
   if( connection->socket != NULL ) {
      rc = apr_socket_close(connection->socket);
      if( result!=APR_SUCCESS )
         result = rc;
      connection->socket=NULL;
   }   
	*connection_ref=NULL;
	return rc;	
}
Example #5
0
lt_http_status_t lt_http_server_run( lt_http_server_t * server )
{
    apr_pool_t * pool = NULL;
    apr_socket_t * client = NULL;
    char error[1025];
    memset( error, 0, 1025 );

    if( server == NULL ) return LT_HTTP_INVALID_ARG;

    /* prepare connection pool */
    apr_pool_create( &pool, server->pool );

    /* make the socket non-blocking */
    if( APR_SUCCESS != apr_socket_opt_set( server->socket,
                    APR_SO_NONBLOCK, 1 ) ) {
        my_perror( "ERROR: apr_socket_opt_set failed with: " );
        return LT_HTTP_INVALID_ARG;
    }

    while( 1 ) {
        apr_status_t rv;

        /* bool reading should be atomic operation so no locking is needed */
        if( server->stoprequested ) {
            break;
        }

        /* clear pool memory */
        apr_pool_clear( pool );

        /* accept new connection */
        rv = apr_socket_accept( &client, server->socket, pool );

        if( APR_STATUS_IS_EAGAIN( rv ) || APR_STATUS_IS_EINTR( rv ) ) {
            /* sleep for 100ms before accepting new client */
            apr_sleep( 100 * 1000 );
            continue;
        }

        if( APR_SUCCESS != rv ) {
            my_perror( "ERROR: apr_socket_accept failed with: " );
            continue;
        }

        /* determine client address */
        {
            apr_sockaddr_t * sa = NULL;
            char * ip = NULL;
            if( APR_SUCCESS != apr_socket_addr_get( &sa,
                            APR_REMOTE, client ) ) {
                my_perror( "ERROR: apr_socket_addr_get failed with: " );
                apr_socket_close( client );
                continue;
            }
            if( APR_SUCCESS != apr_sockaddr_ip_get( &ip, sa ) ) {
                my_perror( "ERROR: apr_sockaddr_ip_get failed with: " );
                apr_socket_close( client );
                continue;
            }
        }


        /* immediatelly start sending HTTP response headers */
        {
            char * headers = apr_pstrcat( pool,
                    "HTTP/1.0 200 OK\r\n"
                    "Content-Length: ",
                    apr_ltoa( pool, server->finfo.size ),
                    "\r\n",
                    "Content-Type: application/octet-stream;"
                    " charset=utf-8\r\n",
                    "Connection: Close\r\n",
                    "\r\n",
                    NULL );
            apr_size_t headers_size = strlen( headers );
            if( APR_SUCCESS != apr_socket_send(
                            client, headers, &headers_size ) ) {
                my_perror( "ERROR: apr_socket_send failed with: " );
                apr_socket_close( client );
                continue;
            }
        }

        /* send file contents */
        {
            apr_off_t offset = 0;
            apr_size_t len = server->finfo.size;

            if( APR_SUCCESS != apr_socket_sendfile(
                            client, server->file, NULL,
                            &offset, &len, 0 ) ) {
                my_perror( "ERROR: apr_socket_sendfile failed with: " );
                apr_socket_close( client );
                continue;
            }
        }

        /* read and discard all headers */
        {
            apr_status_t rv;

            /* set non-block option on client socket */
            if( APR_SUCCESS != apr_socket_timeout_set( client,
                            2 * 1000 * 1000 ) ) {
                my_perror( "ERROR: apr_socket_timeout_set failed with: " );
                apr_socket_close( client );
                continue;
            }

            /* read all data until 2 sec timeout or eof, then proceed to */
            /* close */
            do {
                char buffer[1024];
                apr_size_t len = 1024;
                rv = apr_socket_recv( client, buffer, &len );

                if( APR_STATUS_IS_TIMEUP( rv ) || APR_STATUS_IS_EOF( rv ) ) {
                    break;
                }
            } while( 1 );
        }

        /* close our side of connection */
        if( APR_SUCCESS !=
                    apr_socket_shutdown( client, APR_SHUTDOWN_WRITE ) ) {
            /* we actually don't care about errors arriving during shutdown
             * phase
             * my_perror( "ERROR: apr_socket_shutdown(WRITE) failed with: " );
             */
            apr_socket_close( client );
            continue;
        }

        /* close other side of connection */
        if( APR_SUCCESS !=
                    apr_socket_shutdown( client, APR_SHUTDOWN_READ ) ) {
            /* we actually don't care about errors arriving during shutdown
             * phase
             * my_perror( "ERROR: apr_socket_shutdown(READ) failed with: " );
             */
            apr_socket_close( client );
            continue;
        }

        /* close socket */
        if( APR_SUCCESS != apr_socket_close( client ) ) {
            /* we actually don't care about errors arriving during shutdown
             * phase
             * my_perror( "ERROR: apr_socket_close failed with: " );
             */
            continue;
        }
    }

    return LT_HTTP_SUCCESS;
}
Example #6
0
SWITCH_DECLARE(switch_status_t) switch_socket_shutdown(switch_socket_t *sock, switch_shutdown_how_e how)
{
	return apr_socket_shutdown(sock, (apr_shutdown_how_e) how);
}
Example #7
0
static apr_status_t APR_THREAD_FUNC
uxp_socket_shutdown(apr_socket_t *sock, apr_shutdown_how_e how)
{
    tcn_uxp_conn_t *con = (tcn_uxp_conn_t *)sock;
    return apr_socket_shutdown(con->sock, how);
}
/**
 * Process input stream
 */
static apr_status_t helocon_filter_in(ap_filter_t *f, apr_bucket_brigade *b, ap_input_mode_t mode, apr_read_type_e block, apr_off_t readbytes)
{
    conn_rec *c = f->c;
    my_ctx *ctx = f->ctx;

    // Fail quickly if the connection has already been aborted.
    if (c->aborted) {
        apr_brigade_cleanup(b);
        return APR_ECONNABORTED;
    }
    // Fast passthrough
    if (ctx->phase == PHASE_DONE) {
        return ap_get_brigade(f->next, b, mode, block, readbytes);
    }

    // Process Head
    do {
#ifdef DEBUG
        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, MODULE_NAME "::helocon_filter_in from: %s:%d to port=%d need=%" APR_OFF_T_FMT " phase=%d (1)", _CLIENT_IP, _CLIENT_ADDR->port, c->local_addr->port, ctx->need, ctx->phase);
#endif

        if (APR_BRIGADE_EMPTY(b)) {
#ifdef DEBUG
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, MODULE_NAME "::helocon_filter_in from: %s:%d to port=%d need=%" APR_OFF_T_FMT " phase=%d (2)", _CLIENT_IP, _CLIENT_ADDR->port, c->local_addr->port, ctx->need, ctx->phase);
#endif
            apr_status_t s = ap_get_brigade(f->next, b, ctx->mode, APR_BLOCK_READ, ctx->need);
            if (s != APR_SUCCESS) {
#ifdef DEBUG
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, MODULE_NAME "::helocon_filter_in from: %s:%d to port=%d need=%" APR_OFF_T_FMT " phase=%d (fail)(1)", _CLIENT_IP, _CLIENT_ADDR->port, c->local_addr->port, ctx->need, ctx->phase);
#endif
                return s;
            }
        }
        if (ctx->phase == PHASE_DONE) {
            return APR_SUCCESS;
        }
        if (APR_BRIGADE_EMPTY(b)) {
#ifdef DEBUG
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, MODULE_NAME "::helocon_filter_in from: %s:%d to port=%d need=%" APR_OFF_T_FMT " phase=%d (empty)", _CLIENT_IP, _CLIENT_ADDR->port, c->local_addr->port, ctx->need, ctx->phase);
#endif
            return APR_SUCCESS;
        }
        apr_bucket *e = NULL;
        for (e = APR_BRIGADE_FIRST(b); e != APR_BRIGADE_SENTINEL(b); e = APR_BUCKET_NEXT(e)) {
            if (e->type == NULL) {
#ifdef DEBUG
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, MODULE_NAME "::helocon_filter_in from: %s:%d to port=%d need=%" APR_OFF_T_FMT " phase=%d (type=NULL)", _CLIENT_IP, _CLIENT_ADDR->port, c->local_addr->port, ctx->need, ctx->phase);
#endif
                return APR_SUCCESS;
            }

            // We need more data
            if (ctx->need > 0) {
                const char *str = NULL;
                apr_size_t length = 0;
                apr_status_t s = apr_bucket_read(e, &str, &length, APR_BLOCK_READ);
                if (s != APR_SUCCESS) {
#ifdef DEBUG
                    ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, MODULE_NAME "::helocon_filter_in from: %s:%d to port=%d need=%" APR_OFF_T_FMT " recv=%" APR_OFF_T_FMT " phase=%d readed=%" APR_SIZE_T_FMT " (fail)(2)", _CLIENT_IP, _CLIENT_ADDR->port, c->local_addr->port, ctx->need, ctx->recv, ctx->phase, length);
#endif
                    return s;
                }
#ifdef DEBUG
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, MODULE_NAME "::helocon_filter_in from: %s:%d to port=%d need=%" APR_OFF_T_FMT " recv=%" APR_OFF_T_FMT " phase=%d readed=%" APR_SIZE_T_FMT " (3)", _CLIENT_IP, _CLIENT_ADDR->port, c->local_addr->port, ctx->need, ctx->recv, ctx->phase, length);
#endif
                if (length > 0) {
                    if ((ctx->offset + length) > PROXY_MAX_LENGTH) { // Overflow
                        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, MODULE_NAME "::helocon_filter_in ERROR: PROXY protocol header overflow from=%s to port=%d length=%" APR_OFF_T_FMT, _CLIENT_IP, c->local_addr->port, (ctx->offset + length));
                        goto ABORT_CONN2;
                    }
                    memcpy(ctx->buf + ctx->offset, str, length);
                    if (ctx->pad != ctx->magic) {
                        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, MODULE_NAME "::helocon_filter_in padding magic fail (bad=%d vs good=%d)", ctx->pad, ctx->magic);
                        goto ABORT_CONN;
                    }
                    ctx->offset += length;
                    ctx->recv += length;
                    ctx->need -= length;
                    ctx->buf[ctx->offset] = 0;
                    // delete HEAD
                    if (e->length > length) {
                        apr_bucket_split(e, length);
                    }
                }
                apr_bucket_delete(e);
                if (length == 0) {
#ifdef DEBUG
                    ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, MODULE_NAME "::helocon_filter_in DEBUG bucket flush=%d meta=%d", APR_BUCKET_IS_FLUSH(e) ? 1 : 0, APR_BUCKET_IS_METADATA(e) ? 1 : 0);
#endif
                    continue;
                }
            }
            // Handle GETLINE mode
            if (ctx->mode == AP_MODE_GETLINE) {
                if ((ctx->need > 0) && (ctx->recv > 2)) {
                    char *end = memchr(ctx->buf, '\r', ctx->offset - 1);
                    if (end) {
#ifdef DEBUG
                        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, MODULE_NAME "::helocon_filter_in DEBUG: GETLINE OK");
#endif
                        if ((end[0] == '\r') && (end[1] == '\n')) {
                            ctx->need = 0;
                        }
                    }
                }
            }
            if (ctx->need <= 0) {
#ifdef DEBUG
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, MODULE_NAME "::helocon_filter_in from: %s:%d to port=%d need=%" APR_OFF_T_FMT " recv=%" APR_OFF_T_FMT " phase=%d (4)", _CLIENT_IP, _CLIENT_ADDR->port, c->local_addr->port, ctx->need, ctx->recv, ctx->phase);
#endif
                switch (ctx->phase) {
                case PHASE_WANT_HEAD: {
#ifdef DEBUG
                    ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, MODULE_NAME "::helocon_filter_in from: %s:%d to port=%d phase=%d checking=%s buf=%s", _CLIENT_IP, _CLIENT_ADDR->port, c->local_addr->port, ctx->phase, "HEAD", ctx->buf);
#endif
                    // TEST Command
#ifdef DEBUG
                    ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, MODULE_NAME "::helocon_filter_in DEBUG: CMD=TEST CHECK");
#endif
                    if (strncmp(TEST, ctx->buf, 4) == 0) {
                        apr_socket_t *csd = ap_get_module_config(c->conn_config, &core_module);
                        apr_size_t length = strlen(TEST_RES_OK);
                        apr_socket_send(csd, TEST_RES_OK, &length);
                        apr_socket_shutdown(csd, APR_SHUTDOWN_WRITE);
                        apr_socket_close(csd);

#ifdef DEBUG
                        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, MODULE_NAME "::helocon_filter_in DEBUG: CMD=TEST OK");
#endif

                        // No need to check for SUCCESS, we did that above
                        c->aborted = 1;
                        apr_brigade_cleanup(b);
                        return APR_ECONNABORTED;
                    }
                    // HELO Command
#ifdef DEBUG
                    ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, MODULE_NAME "::helocon_filter_in DEBUG: CMD=HELO CHECK");
#endif
                    if (strncmp(HELO, ctx->buf, 4) == 0) {
#ifdef DEBUG
                        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, MODULE_NAME "::helocon_filter_in DEBUG: CMD=HELO OK");
#endif
                        ctx->phase = PHASE_WANT_BINIP;
                        ctx->mode = AP_MODE_READBYTES;
                        ctx->need = 4;
                        ctx->recv = 0;
                        break;
                    }
                    // PROXY Command
#ifdef DEBUG
                    ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, MODULE_NAME "::helocon_filter_in DEBUG: CMD=PROXY CHECK");
#endif
                    if (strncmp(PROXY, ctx->buf, 4) == 0) {
#ifdef DEBUG
                        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, MODULE_NAME "::helocon_filter_in DEBUG: CMD=PROXY OK");
#endif
                        ctx->phase = PHASE_WANT_LINE;
                        ctx->mode = AP_MODE_GETLINE;
                        ctx->need = PROXY_MAX_LENGTH - ctx->offset;
                        ctx->recv = 0;
                        break;
                    }
                    // ELSE... GET / POST / etc
                    ctx->phase = PHASE_DONE;
#ifdef DEBUG
                    ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, MODULE_NAME "::helocon_filter_in DEBUG from: %s:%d to port=%d newBucket (1) size=%" APR_OFF_T_FMT, _CLIENT_IP, _CLIENT_ADDR->port, c->local_addr->port, ctx->offset);
#endif
                    // Restore original data
                    if (ctx->offset) {
                        e = apr_bucket_heap_create(ctx->buf, ctx->offset, NULL, c->bucket_alloc);
                        APR_BRIGADE_INSERT_HEAD(b, e);
                        goto END_CONN;
                    }
                    break;
                }
                case PHASE_WANT_BINIP: {
#ifdef DEBUG
                    ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, MODULE_NAME "::helocon_filter_in from: %s:%d to port=%d phase=%d checking=%s", _CLIENT_IP, _CLIENT_ADDR->port, c->local_addr->port, ctx->phase, "BINIP");
#endif
                    // REWRITE CLIENT IP
                    const char *new_ip = fromBinIPtoString(c->pool, ctx->buf+4);
                    if (!new_ip) {
                        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, MODULE_NAME "::helocon_filter_in ERROR: HELO+IP invalid");
                        goto ABORT_CONN;
                    }

                    apr_table_set(c->notes, NOTE_REWRITE_IP, new_ip);
                    ctx->phase = PHASE_DONE;
#ifdef DEBUG
                    ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, MODULE_NAME "::helocon_filter_in DEBUG from: %s:%d to port=%d newip=%s", _CLIENT_IP, _CLIENT_ADDR->port, c->local_addr->port, new_ip);
#endif
                    break;
                }
                case PHASE_WANT_LINE: {
#ifdef DEBUG
                    ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, MODULE_NAME "::helocon_filter_in from: %s:%d to port=%d phase=%d checking=%s buf=%s", _CLIENT_IP, _CLIENT_ADDR->port, c->local_addr->port, ctx->phase, "LINE", ctx->buf);
#endif
                    ctx->phase = PHASE_DONE;
                    char *end = memchr(ctx->buf, '\r', ctx->offset - 1);
                    if (!end) {
                        goto ABORT_CONN;
                    }
                    if ((end[0] != '\r') || (end[1] != '\n')) {
                        goto ABORT_CONN;
                    }
                    if (!process_proxy_header(f)) {
                        goto ABORT_CONN;
                    }
                    // Restore original data
                    int count = (ctx->offset - ((end - ctx->buf) + 2));
#ifdef DEBUG
                    ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, MODULE_NAME "::helocon_filter_in DEBUG from: %s:%d to port=%d newBucket (2) size=%d rest=%s", _CLIENT_IP, _CLIENT_ADDR->port, c->local_addr->port, count, end + 2);
#endif
                    if (count > 0) {
                        e = apr_bucket_heap_create(end + 2, count, NULL, c->bucket_alloc);
                        APR_BRIGADE_INSERT_HEAD(b, e);
                        goto END_CONN;
                    }
                    break;
                }
                }
                if (ctx->phase == PHASE_DONE) {
#ifdef DEBUG
                    ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, MODULE_NAME "::helocon_filter_in from: %s:%d to port=%d phase=%d (DONE)", _CLIENT_IP, _CLIENT_ADDR->port, c->local_addr->port, ctx->phase);
#endif
                    ctx->mode = mode;
                    ctx->need = 0;
                    ctx->recv = 0;
                }
                break;
            }
        }
    } while (ctx->phase != PHASE_DONE);

END_CONN:
    return ap_get_brigade(f->next, b, mode, block, readbytes);

ABORT_CONN:
    ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, MODULE_NAME "::helocon_filter_in ERROR: PROXY protocol header invalid from=%s to port=%d", _CLIENT_IP, c->local_addr->port);
ABORT_CONN2:
    c->aborted = 1;
    apr_brigade_cleanup(b);
    return APR_ECONNABORTED;
}
apr_status_t
rainx_http_req(struct req_params_store* rps) {
	const dav_resource* resource = rps->resource;
	char* remote_uri = rps->service_address;
	char* req_type = rps->req_type;
	char* header = rps->header;
	char* data = rps->data_to_send;
	int data_length = rps->data_to_send_size;
	char** reply = &(rps->reply);
	apr_pool_t *local_pool = rps->pool;
	dav_rainx_server_conf *server_conf = resource_get_server_config(resource);

	if (NULL == resource || NULL == remote_uri ||
			NULL == req_type || NULL == server_conf) {
		DAV_ERROR_POOL(local_pool, APR_EINVAL, "One of these params is wrong: "
				"remote_uri=%p, req_type=%p, server_conf=%p"
				" (__FILE__:__LINE__)",
				remote_uri, req_type, server_conf);
		return APR_EINVAL;
	}

	const gboolean is_get = (0 == g_strcmp0(req_type, "GET"));

	/* Isolating Rawx IP and port */
	char *temp_remote_uri = apr_pstrdup(local_pool, remote_uri);
	char* last;
	char* full_remote_url = apr_strtok(temp_remote_uri, "/", &last);
	char* content_hexid = apr_pstrdup(local_pool, remote_uri + strlen(full_remote_url));

	char* remote_ip = NULL;
	char* scope_id = NULL;
	apr_port_t remote_port;
	apr_parse_addr_port(&remote_ip, &scope_id, &remote_port, full_remote_url, local_pool);
	/* ------- */

	/* Preparing the socket */
	apr_socket_t* sock;
	apr_sockaddr_t* sockaddr;
	apr_status_t status;

	if ((status = apr_sockaddr_info_get(&sockaddr, remote_ip, APR_INET, remote_port, 0, local_pool)) != APR_SUCCESS) {
		DAV_DEBUG_REQ(resource->info->request, 0, "unable to connect to the rawx %s", full_remote_url);
		return status;
	}

	if ((status = apr_socket_create(&sock, sockaddr->family, SOCK_STREAM, APR_PROTO_TCP, local_pool)) != APR_SUCCESS) {
		DAV_DEBUG_REQ(resource->info->request, 0, "unable to create a socket to the rawx %s", full_remote_url);
		return status;
	}

	if ((status = apr_socket_timeout_set(sock, server_conf->socket_timeout)) != APR_SUCCESS) {
		DAV_DEBUG_REQ(resource->info->request, 0, "unable to set timeout for the socket to the rawx %s", full_remote_url);
		return status;
	}

	if ((status = apr_socket_connect(sock, sockaddr)) != APR_SUCCESS) {
		DAV_DEBUG_REQ(resource->info->request, 0, "unable to establish the connection to the rawx %s", full_remote_url);
		return status;
	}
	/* ------- */

	/* Forging the message */
	char* forged_header = apr_psprintf(local_pool, "%s %s HTTP/1.1\nHost: %s", req_type, content_hexid, full_remote_url);
	if (header)
		forged_header = apr_psprintf(local_pool, "%s\n%s", forged_header, header);
	if (data)
		forged_header = apr_psprintf(local_pool, "%s\nContent-Length: %d\n\n", forged_header, data_length);
	else
		forged_header = apr_psprintf(local_pool, "%s\n\n", forged_header);
	/* ------- */

	/* Sending the message */
	int remaining_to_send = strlen(forged_header);
	char* ptr_start = forged_header;
	apr_size_t send_buffer_size;
	while (remaining_to_send > 0) {
		if (remaining_to_send < REQUEST_BUFFER_SIZE)
			send_buffer_size = (apr_size_t)remaining_to_send;
		else
			send_buffer_size = REQUEST_BUFFER_SIZE;

		if ((status = apr_socket_send(sock, ptr_start, &send_buffer_size)) != APR_SUCCESS) {
            DAV_DEBUG_REQ(resource->info->request, 0, "failed to send the %s request to the rawx %s", req_type, full_remote_url);
            apr_status_t status_sav = status;
            apr_socket_close(sock);
            return status_sav;
        }

		remaining_to_send -= send_buffer_size;
		ptr_start = ptr_start + send_buffer_size;
	}
	if (NULL != data) {
		remaining_to_send = data_length;
		ptr_start = data;
		while (remaining_to_send > 0) {
			if (remaining_to_send < REQUEST_BUFFER_SIZE)
				send_buffer_size = (apr_size_t)remaining_to_send;
			else
				send_buffer_size = REQUEST_BUFFER_SIZE;

			if ((status = apr_socket_send(sock, ptr_start, &send_buffer_size)) != APR_SUCCESS) {
				DAV_DEBUG_REQ(resource->info->request, 0, "failed to send the %s request to the rawx %s", req_type, full_remote_url);
				apr_status_t status_sav = status;
				apr_socket_close(sock);
				return status_sav;
			}

			remaining_to_send -= send_buffer_size;
			ptr_start = ptr_start + send_buffer_size;
		}
	}

	if (is_get) {
		/* This avoids a ~5s delay in the communication */
		apr_socket_shutdown(sock, APR_SHUTDOWN_WRITE);
	}

	DAV_DEBUG_REQ(resource->info->request, 0, "%s request to the rawx %s sent for the content %s", req_type, full_remote_url, content_hexid);
    /* ------ */

	/* Getting the reply */
	char* reply_ptr = *reply;
	apr_size_t total_size;
	if (!is_get)
		total_size = REPLY_BUFFER_SIZE; // PUT or DELETE
	else
		total_size = MAX_REPLY_HEADER_SIZE + data_length; // GET
	apr_size_t reply_size = (apr_size_t)total_size;
	apr_size_t total_replied_size;
	do {
		status = apr_socket_recv(sock, reply_ptr, &reply_size);
		reply_ptr += reply_size;
		total_replied_size = reply_ptr - *reply;
		/* Leave when OK, or error != timeout, or buffer full */
        if (status == APR_EOF || (status == APR_SUCCESS && !is_get) ||
				(reply_size == 0) ||
				total_replied_size >= total_size) {
            break;
		}
		/* Take care of overflows! */
		reply_size = total_size - total_replied_size;
	} while (total_replied_size < total_size);
	/* ------- */

	apr_socket_close(sock);

	return status;
}
Example #10
0
static int client(apr_pool_t *p, client_socket_mode_t socket_mode,
                  const char *host, int start_server)
{
    apr_status_t rv, tmprv;
    apr_socket_t *sock;
    char buf[120];
    apr_file_t *f = NULL;
    apr_size_t len;
    apr_size_t expected_len;
    apr_off_t current_file_offset;
    apr_hdtr_t hdtr;
    struct iovec headers[3];
    struct iovec trailers[3];
    apr_size_t bytes_read;
    apr_pollset_t *pset;
    apr_int32_t nsocks;
    int connect_tries = 1;
    int i;
    int family;
    apr_sockaddr_t *destsa;
    apr_proc_t server;
    apr_interval_time_t connect_retry_interval = apr_time_from_msec(50);

    if (start_server) {
        spawn_server(p, &server);
        connect_tries = 5; /* give it a chance to start up */
    }

    create_testfile(p, TESTFILE);

    rv = apr_file_open(&f, TESTFILE, APR_FOPEN_READ, 0, p);
    if (rv != APR_SUCCESS) {
        aprerr("apr_file_open()", rv);
    }

    if (!host) {
        host = "127.0.0.1";
    }
    family = APR_INET;
    rv = apr_sockaddr_info_get(&destsa, host, family, TESTSF_PORT, 0, p);
    if (rv != APR_SUCCESS) {
        aprerr("apr_sockaddr_info_get()", rv);
    }

    while (connect_tries--) {
        apr_setup(p, &sock, &family);
        rv = apr_socket_connect(sock, destsa);
        if (connect_tries && APR_STATUS_IS_ECONNREFUSED(rv)) {
            apr_status_t tmprv = apr_socket_close(sock);
            if (tmprv != APR_SUCCESS) {
                aprerr("apr_socket_close()", tmprv);
            }
            apr_sleep(connect_retry_interval);
            connect_retry_interval *= 2;
        }
        else {
            break;
        }
    }
    if (rv != APR_SUCCESS) {
        aprerr("apr_socket_connect()", rv);
    }

    switch(socket_mode) {
    case BLK:
        /* leave it blocking */
        break;
    case NONBLK:
        /* set it non-blocking */
        rv = apr_socket_opt_set(sock, APR_SO_NONBLOCK, 1);
        if (rv != APR_SUCCESS) {
            aprerr("apr_socket_opt_set(APR_SO_NONBLOCK)", rv);
        }
        break;
    case TIMEOUT:
        /* set a timeout */
        rv = apr_socket_timeout_set(sock, 100 * APR_USEC_PER_SEC);
        if (rv != APR_SUCCESS) {
            aprerr("apr_socket_opt_set(APR_SO_NONBLOCK)", rv);
            exit(1);
        }
        break;
    default:
        assert(1 != 1);
    }

    printf("Sending the file...\n");

    hdtr.headers = headers;
    hdtr.numheaders = 3;
    hdtr.headers[0].iov_base = HDR1;
    hdtr.headers[0].iov_len  = strlen(hdtr.headers[0].iov_base);
    hdtr.headers[1].iov_base = HDR2;
    hdtr.headers[1].iov_len  = strlen(hdtr.headers[1].iov_base);
    hdtr.headers[2].iov_base = malloc(HDR3_LEN);
    assert(hdtr.headers[2].iov_base);
    memset(hdtr.headers[2].iov_base, HDR3_CHAR, HDR3_LEN);
    hdtr.headers[2].iov_len  = HDR3_LEN;

    hdtr.trailers = trailers;
    hdtr.numtrailers = 3;
    hdtr.trailers[0].iov_base = TRL1;
    hdtr.trailers[0].iov_len  = strlen(hdtr.trailers[0].iov_base);
    hdtr.trailers[1].iov_base = TRL2;
    hdtr.trailers[1].iov_len  = strlen(hdtr.trailers[1].iov_base);
    hdtr.trailers[2].iov_base = malloc(TRL3_LEN);
    memset(hdtr.trailers[2].iov_base, TRL3_CHAR, TRL3_LEN);
    assert(hdtr.trailers[2].iov_base);
    hdtr.trailers[2].iov_len  = TRL3_LEN;

    expected_len = 
        strlen(HDR1) + strlen(HDR2) + HDR3_LEN +
        strlen(TRL1) + strlen(TRL2) + TRL3_LEN +
        FILE_LENGTH;
    
    if (socket_mode == BLK) {
        current_file_offset = 0;
        len = FILE_LENGTH;
        rv = apr_socket_sendfile(sock, f, &hdtr, &current_file_offset, &len, 0);
        if (rv != APR_SUCCESS) {
            aprerr("apr_socket_sendfile()", rv);
        }
        
        printf("apr_socket_sendfile() updated offset with %ld\n",
               (long int)current_file_offset);
        
        printf("apr_socket_sendfile() updated len with %ld\n",
               (long int)len);
        
        printf("bytes really sent: %" APR_SIZE_T_FMT "\n",
               expected_len);

        if (len != expected_len) {
            fprintf(stderr, "apr_socket_sendfile() didn't report the correct "
                    "number of bytes sent!\n");
            exit(1);
        }
    }
    else {
        /* non-blocking... wooooooo */
        apr_size_t total_bytes_sent;
        apr_pollfd_t pfd;

        pset = NULL;
        rv = apr_pollset_create(&pset, 1, p, 0);
        assert(!rv);
        pfd.p = p;
        pfd.desc_type = APR_POLL_SOCKET;
        pfd.reqevents = APR_POLLOUT;
        pfd.rtnevents = 0;
        pfd.desc.s = sock;
        pfd.client_data = NULL;

        rv = apr_pollset_add(pset, &pfd);        
        assert(!rv);

        total_bytes_sent = 0;
        current_file_offset = 0;
        len = FILE_LENGTH;
        do {
            apr_size_t tmplen;

            tmplen = len; /* bytes remaining to send from the file */
            printf("Calling apr_socket_sendfile()...\n");
            printf("Headers (%d):\n", hdtr.numheaders);
            for (i = 0; i < hdtr.numheaders; i++) {
                printf("\t%ld bytes (%c)\n",
                       (long)hdtr.headers[i].iov_len,
                       *(char *)hdtr.headers[i].iov_base);
            }
            printf("File: %ld bytes from offset %ld\n",
                   (long)tmplen, (long)current_file_offset);
            printf("Trailers (%d):\n", hdtr.numtrailers);
            for (i = 0; i < hdtr.numtrailers; i++) {
                printf("\t%ld bytes\n",
                       (long)hdtr.trailers[i].iov_len);
            }

            rv = apr_socket_sendfile(sock, f, &hdtr, &current_file_offset, &tmplen, 0);
            printf("apr_socket_sendfile()->%d, sent %ld bytes\n", rv, (long)tmplen);
            if (rv) {
                if (APR_STATUS_IS_EAGAIN(rv)) {
                    assert(tmplen == 0);
                    nsocks = 1;
                    tmprv = apr_pollset_poll(pset, -1, &nsocks, NULL);
                    assert(!tmprv);
                    assert(nsocks == 1);
                    /* continue; */
                }
            }

            total_bytes_sent += tmplen;

            /* Adjust hdtr to compensate for partially-written
             * data.
             */

            /* First, skip over any header data which might have
             * been written.
             */
            while (tmplen && hdtr.numheaders) {
                if (tmplen >= hdtr.headers[0].iov_len) {
                    tmplen -= hdtr.headers[0].iov_len;
                    --hdtr.numheaders;
                    ++hdtr.headers;
                }
                else {
                    hdtr.headers[0].iov_len -= tmplen;
                    hdtr.headers[0].iov_base = 
			(char*) hdtr.headers[0].iov_base + tmplen;
                    tmplen = 0;
                }
            }

            /* Now, skip over any file data which might have been
             * written.
             */

            if (tmplen <= len) {
                current_file_offset += tmplen;
                len -= tmplen;
                tmplen = 0;
            }
            else {
                tmplen -= len;
                len = 0;
                current_file_offset = 0;
            }

            /* Last, skip over any trailer data which might have
             * been written.
             */

            while (tmplen && hdtr.numtrailers) {
                if (tmplen >= hdtr.trailers[0].iov_len) {
                    tmplen -= hdtr.trailers[0].iov_len;
                    --hdtr.numtrailers;
                    ++hdtr.trailers;
                }
                else {
                    hdtr.trailers[0].iov_len -= tmplen;
                    hdtr.trailers[0].iov_base = 
			(char *)hdtr.trailers[0].iov_base + tmplen;
                    tmplen = 0;
                }
            }

        } while (total_bytes_sent < expected_len &&
                 (rv == APR_SUCCESS || 
                 (APR_STATUS_IS_EAGAIN(rv) && socket_mode != TIMEOUT)));
        if (total_bytes_sent != expected_len) {
            fprintf(stderr,
                    "client problem: sent %ld of %ld bytes\n",
                    (long)total_bytes_sent, (long)expected_len);
            exit(1);
        }

        if (rv) {
            fprintf(stderr,
                    "client problem: rv %d\n",
                    rv);
            exit(1);
        }
    }
    
    current_file_offset = 0;
    rv = apr_file_seek(f, APR_CUR, &current_file_offset);
    if (rv != APR_SUCCESS) {
        aprerr("apr_file_seek()", rv);
    }

    printf("After apr_socket_sendfile(), the kernel file pointer is "
           "at offset %ld.\n",
           (long int)current_file_offset);

    rv = apr_socket_shutdown(sock, APR_SHUTDOWN_WRITE);
    if (rv != APR_SUCCESS) {
        aprerr("apr_socket_shutdown()", rv);
    }

    /* in case this is the non-blocking test, set socket timeout;
     * we're just waiting for EOF */

    rv = apr_socket_timeout_set(sock, apr_time_from_sec(3));
    if (rv != APR_SUCCESS) {
        aprerr("apr_socket_timeout_set()", rv);
    }
    
    bytes_read = 1;
    rv = apr_socket_recv(sock, buf, &bytes_read);
    if (rv != APR_EOF) {
        aprerr("apr_socket_recv() (expected APR_EOF)", rv);
    }
    if (bytes_read != 0) {
        fprintf(stderr, "We expected to get 0 bytes read with APR_EOF\n"
                "but instead we read %ld bytes.\n",
                (long int)bytes_read);
        exit(1);
    }

    printf("client: apr_socket_sendfile() worked as expected!\n");

    rv = apr_file_remove(TESTFILE, p);
    if (rv != APR_SUCCESS) {
        aprerr("apr_file_remove()", rv);
    }

    if (start_server) {
        apr_exit_why_e exitwhy;
        apr_size_t nbytes;
        char responsebuf[1024];
        int exitcode;

        rv = apr_file_pipe_timeout_set(server.out, apr_time_from_sec(2));
        if (rv != APR_SUCCESS) {
            aprerr("apr_file_pipe_timeout_set()", rv);
        }
        nbytes = sizeof(responsebuf);
        rv = apr_file_read(server.out, responsebuf, &nbytes);
        if (rv != APR_SUCCESS) {
            aprerr("apr_file_read() messages from server", rv);
        }
        printf("%.*s", (int)nbytes, responsebuf);
        rv = apr_proc_wait(&server, &exitcode, &exitwhy, APR_WAIT);
        if (rv != APR_CHILD_DONE) {
            aprerr("apr_proc_wait() (expected APR_CHILD_DONE)", rv);
        }
        if (exitcode != 0) {
            fprintf(stderr, "sendfile server returned %d\n", exitcode);
            exit(1);
        }
    }

    return 0;
}
static void tcp_proxy_shutdown_socket(TcpProxyData * tpd)
{
    if (tpd && tpd->tcpsocket)
        apr_socket_shutdown(tpd->tcpsocket, APR_SHUTDOWN_READWRITE);
}
Example #12
0
int main(int argc, char *argv[])
{
    apr_pool_t *context;
    apr_socket_t *sock;
    apr_size_t length;
    apr_status_t stat;
    char datasend[STRLEN] = "Send data test";
    char datarecv[STRLEN];
    char msgbuf[80];
    char *local_ipaddr, *remote_ipaddr;
    char *dest = "127.0.0.1";
    apr_port_t local_port, remote_port;
    apr_interval_time_t timeout = apr_time_from_sec(2);
    apr_sockaddr_t *local_sa, *remote_sa;

    setbuf(stdout, NULL);
    if (argc > 1) {
        dest = argv[1];
    }

    if (argc > 2) {
        timeout = atoi(argv[2]);
    }

    fprintf(stdout, "Initializing.........");
    if (apr_initialize() != APR_SUCCESS) {
        fprintf(stderr, "Something went wrong\n");
        exit(-1);
    }
    fprintf(stdout, "OK\n");
    atexit(apr_terminate);

    fprintf(stdout, "Creating context.......");
    if (apr_pool_create(&context, NULL) != APR_SUCCESS) {
        fprintf(stderr, "Something went wrong\n");
        exit(-1);
    }
    fprintf(stdout, "OK\n");

    fprintf(stdout,"\tClient:  Making socket address...............");
    if ((stat = apr_sockaddr_info_get(&remote_sa, dest, APR_UNSPEC, 8021, 0, context)) 
        != APR_SUCCESS) {
        fprintf(stdout, "Failed!\n");
        fprintf(stdout, "Address resolution failed for %s: %s\n", 
                dest, apr_strerror(stat, msgbuf, sizeof(msgbuf)));
        exit(-1);
    }
    fprintf(stdout,"OK\n");

    fprintf(stdout, "\tClient:  Creating new socket.......");
    if (apr_socket_create(&sock, remote_sa->family, SOCK_STREAM,
                          context) != APR_SUCCESS) {
        fprintf(stderr, "Couldn't create socket\n");
        exit(-1);
    }
    fprintf(stdout, "OK\n");

    fprintf(stdout, "\tClient:  Setting socket timeout.......");
    stat = apr_socket_timeout_set(sock, timeout);
    if (stat) {
        fprintf(stderr, "Problem setting timeout: %d\n", stat);
        exit(-1);
    }
    fprintf(stdout, "OK\n");

    fprintf(stdout, "\tClient:  Connecting to socket.......");

    stat = apr_socket_connect(sock, remote_sa);

    if (stat != APR_SUCCESS) {
        apr_socket_close(sock);
        fprintf(stderr, "Could not connect: %s (%d)\n", 
		apr_strerror(stat, msgbuf, sizeof(msgbuf)), stat);
        fflush(stderr);
        exit(-1);
    }
    fprintf(stdout, "OK\n");

    apr_socket_addr_get(&remote_sa, APR_REMOTE, sock);
    apr_sockaddr_ip_get(&remote_ipaddr, remote_sa);
    apr_sockaddr_port_get(&remote_port, remote_sa);
    apr_socket_addr_get(&local_sa, APR_LOCAL, sock);
    apr_sockaddr_ip_get(&local_ipaddr, local_sa);
    apr_sockaddr_port_get(&local_port, local_sa);
    fprintf(stdout, "\tClient socket: %s:%u -> %s:%u\n", local_ipaddr, local_port, remote_ipaddr, remote_port);

    fprintf(stdout, "\tClient:  Trying to send data over socket.......");
    length = STRLEN;
    if ((stat = apr_socket_send(sock, datasend, &length) != APR_SUCCESS)) {
        apr_socket_close(sock);
        fprintf(stderr, "Problem sending data: %s (%d)\n",
		apr_strerror(stat, msgbuf, sizeof(msgbuf)), stat);
        exit(-1);
    }
    fprintf(stdout, "OK\n");
   
    length = STRLEN; 
    fprintf(stdout, "\tClient:  Trying to receive data over socket.......");

    if ((stat = apr_socket_recv(sock, datarecv, &length)) != APR_SUCCESS) {
        apr_socket_close(sock);
        fprintf(stderr, "Problem receiving data: %s (%d)\n", 
		apr_strerror(stat, msgbuf, sizeof(msgbuf)), stat);
        exit(-1);
    }
    if (strcmp(datarecv, "Recv data test")) {
        apr_socket_close(sock);
        fprintf(stderr, "I did not receive the correct data %s\n", datarecv);
        exit(-1);
    }
    fprintf(stdout, "OK\n");

    fprintf(stdout, "\tClient:  Shutting down socket.......");
    if (apr_socket_shutdown(sock, APR_SHUTDOWN_WRITE) != APR_SUCCESS) {
        apr_socket_close(sock);
        fprintf(stderr, "Could not shutdown socket\n");
        exit(-1);
    }
    fprintf(stdout, "OK\n");

    fprintf(stdout, "\tClient:  Closing down socket.......");
    if (apr_socket_close(sock) != APR_SUCCESS) {
        fprintf(stderr, "Could not shutdown socket\n");
        exit(-1);
    }
    fprintf(stdout, "OK\n");

    return 1;
}
Example #13
0
void kdsock_comm_shutdown(kdsock_comm *self, int how) {
    if (self->apr_sock)
        apr_socket_shutdown(self->apr_sock, how);
}