Very interesting Michal.

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

Reply via email to