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;