Hi all:

Attached is a patch to add support for SCTP to apache for those
O/S's that have it.

Now a note about this patch..

The idea behind this is that SCTP is automatically enabled if
available... i.e. there is no flag to turn it on/off.. if you say
listen 80

and have sctp.. you get a listener on both TCP and SCTP port 80.

Now the reason I picked this method is:

a) A port/socket listening is a small amount of overhead...
b) TCP and SCTP are both congestion controlled protocols so
   there should be no threat to the stability of the Big I due
   to the use of SCTP and http (unlike using http with UDP).
c) It seemed like a logical thing to do :-)

Now I suppose the alternative is to expand the config file with
a

listen,tcp: 80
listen,sctp: 80

etc...

But this seemed a bit overkill to avoid listening on one additional
socket...

Comments would be most welcome..

R
--
Randall R. Stewart
[EMAIL PROTECTED] 815-342-5222 (cell phone)
Index: server/listen.c
===================================================================
RCS file: /home/cvspublic/httpd-2.0/server/listen.c,v
retrieving revision 1.82
diff -u -r1.82 listen.c
--- server/listen.c     31 Jul 2002 12:44:55 -0000      1.82
+++ server/listen.c     1 Nov 2002 16:51:37 -0000
@@ -229,7 +229,8 @@
         apr_socket_t *tmp_sock;
         apr_sockaddr_t *sa;
 
-        if ((sock_rv = apr_socket_create(&tmp_sock, APR_INET6, SOCK_STREAM, p)) 
+        if ((sock_rv = apr_socket_create_ex(&tmp_sock, APR_INET6, SOCK_STREAM, 
+                                            APR_PROTO_TCP , p)) 
             == APR_SUCCESS &&
             apr_sockaddr_info_get(&sa, NULL, APR_INET6, 0, 0, p) == APR_SUCCESS &&
             apr_bind(tmp_sock, sa) == APR_SUCCESS) { 
@@ -253,6 +254,9 @@
     apr_status_t status;
     apr_port_t oldport;
     apr_sockaddr_t *sa;
+#if APR_HAVE_SCTP
+    ap_listen_rec *new2;
+#endif
 
     if (!addr) { /* don't bind to specific interface */
         find_default_family(process->pool);
@@ -280,9 +284,27 @@
             apr_sockaddr_port_get(&oldport, sa);
             if (!strcmp(sa->hostname, addr) && port == oldport) {
                 /* re-use existing record */
+#if APR_HAVE_SCTP
+                int protocol;
+                new = *walk;
+                if(new->next) {
+                    apr_socket_protocol_get(new->next->sd,&protocol);
+                }
+                if(new->next && (protocol == IPPROTO_SCTP)) {
+                        /* Next one is a clone of this one so
+                         * take it too.
+                         */
+                        *walk = new->next->next;
+                        new->next->next = ap_listeners;
+                } else {
+                        *walk = new->next;
+                        new->next = ap_listeners;
+                }
+#else
                 new = *walk;
                 *walk = new->next;
                 new->next = ap_listeners;
+#endif
                 ap_listeners = new;
                 return NULL;
             }
@@ -300,15 +322,44 @@
                       addr);
         return "Listen setup failed";
     }
-    if ((status = apr_socket_create(&new->sd,
-                                    new->bind_addr->family,
-                                    SOCK_STREAM, process->pool))
+    if ((status = apr_socket_create_ex(&new->sd,
+                                       new->bind_addr->family,
+                                       SOCK_STREAM, 
+                                       IPPROTO_TCP , 
+                                       process->pool))
         != APR_SUCCESS) {
         ap_log_perror(APLOG_MARK, APLOG_CRIT, status, process->pool,
                       "alloc_listener: failed to get a socket for %s", addr);
         return "Listen setup failed";
     }
+#if APR_HAVE_SCTP
+    new2 = apr_palloc(process->pool, sizeof(ap_listen_rec));
+    new2->active = 0;
+    if ((status = apr_sockaddr_info_get(&new2->bind_addr, addr, APR_UNSPEC,
+                                        port, 0, process->pool))
+        != APR_SUCCESS) {
+        ap_log_perror(APLOG_MARK, APLOG_INFO, status, process->pool,
+                      "alloc_listener: SCTP socket not available for listen on %s", 
+addr);
+        new->next = ap_listeners;
+        ap_listeners = new;
+        return NULL;
+    }
+    if ((status = apr_socket_create_ex(&new2->sd,
+                                       new2->bind_addr->family,
+                                       SOCK_STREAM, 
+                                       IPPROTO_SCTP , 
+                                       process->pool))
+        != APR_SUCCESS) {
+        ap_log_perror(APLOG_MARK, APLOG_INFO, status, process->pool,
+                      "alloc_listener: SCTP socket not available for listen on %s", 
+addr);
+        new->next = ap_listeners;
+        ap_listeners = new;
+        return NULL;
 
+    }
+    new2->next = ap_listeners;
+    ap_listeners = new2;
+#endif
     new->next = ap_listeners;
     ap_listeners = new;
     return NULL;

Reply via email to