I would like to commit your UDP listener patch to apache 2.1's source tree.
(providing other people don't have any major objections)
Of course.. I would need your permission to do this first.
Regards Ian
Michal Szymaniak wrote:
Hello,
for those of you who are interested in doing weird things in Apache, I would like to advertise NetAirt -- a brand new redirection system inside an Apache module. It supports both DNS- and HTTP-based redirection, and can be used to implement Akamai-like 2-level redirection system. And yes, it implements a UDP server inside an Apache module (although with a few-lines patch).
As for replica selection, NetAirt can select topologically-proximal replica servers based to network distance (AS-hops); classical stuff, such as normal DNS operation (name-to-IP), and round-robin address selection is also supported.
Available at: http://www.globule.org/netairt/ (src, docs, relevant papers)
Live demo: http://lotus.cs.vu.nl/
Comments welcome :-)
Enjoy, M. -- Michal Szymaniak | mailto:[EMAIL PROTECTED] | http://www.cs.vu.nl/~mszyman
diff -rc httpd-2.0.46-orig/include/ap_listen.h httpd-2.0.46-patched/include/ap_listen.h *** httpd-2.0.46-orig/include/ap_listen.h Mon Feb 3 18:31:29 2003 --- httpd-2.0.46-patched/include/ap_listen.h Tue Jun 17 12:30:03 2003 *************** *** 65,70 **** --- 65,72 ---- typedef struct ap_listen_rec ap_listen_rec; typedef apr_status_t (*accept_function)(void **csd, ap_listen_rec *lr, apr_pool_t *ptrans); + typedef apr_status_t (*socket_process_function)(void *csd, ap_listen_rec *lr, server_rec *s, apr_pool_t *ptrans); + #define AP_LISTEN_REC_KEY "A key to the ap_listen_rec structure NetAirt attaches to the transaction pool" /** * Apache's listeners record. These are used in the Multi-Processing Modules *************** *** 88,93 **** --- 90,99 ---- */ accept_function accept_func; /** + * The 'process connection' function for this socket + */ + socket_process_function process_func; + /** * Is this socket currently active */ int active; *************** *** 98,103 **** --- 104,110 ---- * The global list of ap_listen_rec structures */ AP_DECLARE_DATA extern ap_listen_rec *ap_listeners; + AP_DECLARE_DATA extern ap_listen_rec *ap_old_listeners; /** * Setup all of the defaults for the listener list diff -rc httpd-2.0.46-orig/server/core.c httpd-2.0.46-patched/server/core.c *** httpd-2.0.46-orig/server/core.c Tue May 13 18:01:04 2003 --- httpd-2.0.46-patched/server/core.c Tue Jun 17 12:33:32 2003 *************** *** 4196,4202 **** apr_bucket_alloc_t *alloc) { apr_status_t rv; ! conn_rec *c = (conn_rec *) apr_pcalloc(ptrans, sizeof(conn_rec)); c->sbh = sbh; (void)ap_update_child_status(c->sbh, SERVER_BUSY_READ, (request_rec *)NULL); --- 4196,4212 ---- apr_bucket_alloc_t *alloc) { apr_status_t rv; ! conn_rec *c; ! ap_listen_rec * lr = NULL; ! ! rv = apr_pool_userdata_get((void**)&lr,AP_LISTEN_REC_KEY,ptrans); ! if (rv == APR_SUCCESS && lr && lr->process_func) { ! apr_pool_userdata_set(NULL,AP_LISTEN_REC_KEY,NULL,ptrans); ! lr->process_func(csd,lr,server,ptrans); ! return NULL; ! } ! ! c = (conn_rec *) apr_pcalloc(ptrans, sizeof(conn_rec)); c->sbh = sbh; (void)ap_update_child_status(c->sbh, SERVER_BUSY_READ, (request_rec *)NULL); diff -rc httpd-2.0.46-orig/server/listen.c httpd-2.0.46-patched/server/listen.c *** httpd-2.0.46-orig/server/listen.c Mon Mar 31 06:30:52 2003 --- httpd-2.0.46-patched/server/listen.c Tue Jun 17 12:36:36 2003 *************** *** 72,77 **** --- 72,78 ---- #include "mpm_common.h" ap_listen_rec *ap_listeners = NULL; + ap_listen_rec *ap_old_listeners = NULL; #if APR_HAVE_IPV6 static int default_family = APR_UNSPEC; *************** *** 79,85 **** static int default_family = APR_INET; #endif - static ap_listen_rec *old_listeners; static int ap_listenbacklog; static int send_buffer_size; --- 80,85 ---- *************** *** 218,224 **** #else server->accept_func = NULL; #endif ! return APR_SUCCESS; } --- 218,224 ---- #else server->accept_func = NULL; #endif ! server->process_func = NULL; return APR_SUCCESS; } *************** *** 294,305 **** } /* see if we've got an old listener for this address:port */ ! for (walk = &old_listeners; *walk; walk = &(*walk)->next) { sa = (*walk)->bind_addr; /* Some listeners are not real so they will not have a bind_addr. */ if (sa) { apr_sockaddr_port_get(&oldport, sa); ! if (!strcmp(sa->hostname, addr) && port == oldport) { /* re-use existing record */ new = *walk; *walk = new->next; --- 294,305 ---- } /* see if we've got an old listener for this address:port */ ! for (walk = &ap_old_listeners; *walk; walk = &(*walk)->next) { sa = (*walk)->bind_addr; /* Some listeners are not real so they will not have a bind_addr. */ if (sa) { apr_sockaddr_port_get(&oldport, sa); ! if (!strcmp(sa->hostname, addr) && port == oldport && !(*walk)->process_func) { /* re-use existing record */ new = *walk; *walk = new->next; *************** *** 365,376 **** } /* close the old listeners */ ! for (lr = old_listeners; lr; lr = next) { apr_socket_close(lr->sd); lr->active = 0; next = lr->next; } ! old_listeners = NULL; /* we come through here on both passes of the open logs phase * only register the cleanup once... otherwise we try to close --- 365,376 ---- } /* close the old listeners */ ! for (lr = ap_old_listeners; lr; lr = next) { apr_socket_close(lr->sd); lr->active = 0; next = lr->next; } ! ap_old_listeners = NULL; /* we come through here on both passes of the open logs phase * only register the cleanup once... otherwise we try to close *************** *** 405,411 **** void ap_listen_pre_config(void) { ! old_listeners = ap_listeners; ap_listeners = NULL; ap_listenbacklog = DEFAULT_LISTENBACKLOG; } --- 405,411 ---- void ap_listen_pre_config(void) { ! ap_old_listeners = ap_listeners; ap_listeners = NULL; ap_listenbacklog = DEFAULT_LISTENBACKLOG; } diff -rc httpd-2.0.46-orig/server/mpm/prefork/prefork.c httpd-2.0.46-patched/server/mpm/prefork/prefork.c *** httpd-2.0.46-orig/server/mpm/prefork/prefork.c Mon Feb 3 18:32:05 2003 --- httpd-2.0.46-patched/server/mpm/prefork/prefork.c Tue Jun 17 12:37:12 2003 *************** *** 590,595 **** --- 590,596 ---- sizeof(*listensocks) * (num_listensocks)); for (lr = ap_listeners, i = 0; i < num_listensocks; lr = lr->next, i++) { listensocks[i].accept_func = lr->accept_func; + listensocks[i].process_func = lr->process_func; listensocks[i].sd = lr->sd; }