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;
}
