char recv_buffer_size_set;
apr_size_t io_buffer_size;
char io_buffer_size_set;
+ char keepalive;
proxy_conn_pool *cp; /* Connection pool to use */
void *opaque; /* per scheme worker data */
};
PROXY_DECLARE(int) ap_proxy_pre_http_request(conn_rec *c, request_rec *r);
PROXY_DECLARE(apr_status_t) ap_proxy_string_read(conn_rec *c, apr_bucket_brigade *bb, char *buff, size_t bufflen, int *eos);
PROXY_DECLARE(void) ap_proxy_table_unmerge(apr_pool_t *p, apr_table_t *t, char *key);
+/* DEPRECATED (will be replaced with ap_proxy_connect_backend */
PROXY_DECLARE(int) ap_proxy_connect_to_backend(apr_socket_t **, const char *, apr_sockaddr_t *, const char *, proxy_server_conf *, server_rec *, apr_pool_t *);
PROXY_DECLARE(int) ap_proxy_ssl_enable(conn_rec *c);
PROXY_DECLARE(int) ap_proxy_ssl_disable(conn_rec *c);
char *server_portstr, int server_portstr_size);
PROXY_DECLARE(apr_status_t) ap_proxy_destroy_connection(proxy_conn_rec *conn);
PROXY_DECLARE(apr_status_t) ap_proxy_close_connection(proxy_conn_rec *conn);
-
+PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function, proxy_conn_rec *conn, proxy_worker *worker,
+ proxy_server_conf *conf, server_rec *s);
/* For proxy_util */
extern module PROXY_DECLARE_DATA proxy_module;
return access_status;
}
+/* DEPRECATED */
PROXY_DECLARE(int) ap_proxy_connect_to_backend(apr_socket_t **newsock,
const char *proxy_function,
apr_sockaddr_t *backend_addr,
char test_buffer[1];
apr_status_t socket_status;
apr_interval_time_t current_timeout;
-
+
/* save timeout */
apr_socket_timeout_get(sock, ¤t_timeout);
/* set no timeout */
else
return 1;
}
+
+PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function,
+ proxy_conn_rec *conn,
+ proxy_worker *worker,
+ proxy_server_conf *conf,
+ server_rec *s)
+{
+ apr_status_t rv;
+ int connected = 0;
+ int loglevel;
+ apr_sockaddr_t *backend_addr = worker->cp->addr;
+ apr_socket_t *newsock;
+
+ if (conn->sock) {
+ /* This increases the connection pool size
+ * but the number of dropped connections is
+ * relatively small compared to connection lifetime
+ */
+ if (!(connected = is_socket_connected(conn->sock))) {
+ apr_socket_close(conn->sock);
+ conn->sock = NULL;
+ }
+ }
+
+ while (backend_addr && !connected) {
+ if ((rv = apr_socket_create(&newsock, backend_addr->family,
+ SOCK_STREAM, 0, conn->pool)) != APR_SUCCESS) {
+ loglevel = backend_addr->next ? APLOG_DEBUG : APLOG_ERR;
+ ap_log_error(APLOG_MARK, loglevel, rv, s,
+ "proxy: %s: error creating fam %d socket for target %s",
+ proxy_function,
+ backend_addr->family,
+ worker->hostname);
+ /* this could be an IPv6 address from the DNS but the
+ * local machine won't give us an IPv6 socket; hopefully the
+ * DNS returned an additional address to try
+ */
+ backend_addr = backend_addr->next;
+ continue;
+ }
+
+#if !defined(TPF) && !defined(BEOS)
+ if (conf->recv_buffer_size > 0 &&
+ (rv = apr_socket_opt_set(newsock, APR_SO_RCVBUF,
+ conf->recv_buffer_size))) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
+ "apr_socket_opt_set(SO_RCVBUF): Failed to set "
+ "ProxyReceiveBufferSize, using default");
+ }
+#endif
+
+ /* Set a timeout on the socket */
+ if (worker->timeout_set == 1) {
+ apr_socket_timeout_set(newsock, worker->timeout);
+ }
+ else {
+ apr_socket_timeout_set(newsock, s->timeout);
+ }
+ /* Set a keepalive option */
+ if (worker->keepalive) {
+ if ((rv = apr_socket_opt_set(newsock,
+ APR_SO_KEEPALIVE, 1)) != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
+ "apr_socket_opt_set(SO_KEEPALIVE): Failed to set"
+ " Keepalive");
+ }
+ }
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+ "proxy: %s: fam %d socket created to connect to %s",
+ proxy_function, backend_addr->family, worker->hostname);
+
+ /* make the connection out of the socket */
+ rv = apr_socket_connect(newsock, backend_addr);
+
+ /* if an error occurred, loop round and try again */
+ if (rv != APR_SUCCESS) {
+ apr_socket_close(newsock);
+ loglevel = backend_addr->next ? APLOG_DEBUG : APLOG_ERR;
+ ap_log_error(APLOG_MARK, loglevel, rv, s,
+ "proxy: %s: attempt to connect to %pI (%s) failed",
+ proxy_function,
+ backend_addr,
+ worker->hostname);
+ backend_addr = backend_addr->next;
+ continue;
+ }
+ conn->sock = newsock;
+ conn->worker = worker;
+ connected = 1;
+ }
+ return connected ? 0 : 1;
+}