Index: httpd-2.0/include/ap_listen.h
===================================================================
RCS file: /home/cvspublic/httpd-2.0/include/ap_listen.h,v
retrieving revision 1.30
diff -u -r1.30 ap_listen.h
--- httpd-2.0/include/ap_listen.h	13 Mar 2002 20:47:42 -0000	1.30
+++ httpd-2.0/include/ap_listen.h	13 Aug 2002 22:04:08 -0000
@@ -144,9 +144,14 @@
 #define LISTEN_COMMANDS	\
 AP_INIT_TAKE1("ListenBacklog", ap_set_listenbacklog, NULL, RSRC_CONF, \
   "Maximum length of the queue of pending connections, as used by listen(2)"), \
-AP_INIT_TAKE1("Listen", ap_set_listener, NULL, RSRC_CONF, \
+AP_INIT_TAKE1("Listen", ap_set_listener, (void*)SOCK_STREAM, RSRC_CONF, \
   "A port number or a numeric IP address and a port number"), \
 AP_INIT_TAKE1("SendBufferSize", ap_set_send_buffer_size, NULL, RSRC_CONF, \
   "Send buffer size in bytes")
+/* UDP "listen" function"  */
+
+#define UDP_LISTEN_COMMANDS     \
+AP_INIT_TAKE1("UDPListen", ap_set_listener, (void*)SOCK_DGRAM, RSRC_CONF, \
+  "A UDP port number or a numeric IP address and a UDP port number")
 
 #endif
Index: httpd-2.0/os/unix/unixd.c
===================================================================
RCS file: /home/cvspublic/httpd-2.0/os/unix/unixd.c,v
retrieving revision 1.55
diff -u -r1.55 unixd.c
--- httpd-2.0/os/unix/unixd.c	27 Jun 2002 10:47:49 -0000	1.55
+++ httpd-2.0/os/unix/unixd.c	13 Aug 2002 22:04:08 -0000
@@ -582,3 +582,49 @@
     return status;
 }
 
+AP_DECLARE(apr_status_t) unixd_pop_socket(void **newsock, ap_listen_rec * lr,
+                                          apr_pool_t * ptrans)
+{
+  int type;
+
+  apr_os_sock_get_type(&type, lr->sd);
+  if (type == SOCK_DGRAM) {
+    return unixd_udp_connect(newsock, lr, ptrans);
+  }
+  else {
+    return unixd_accept(newsock, lr, ptrans);
+  }
+}
+
+
+AP_DECLARE(apr_status_t) unixd_udp_connect(void **newsock, ap_listen_rec * lr,
+                                           apr_pool_t * ptrans)
+{
+  apr_socket_t *csd;
+  apr_status_t status;
+  int sockdes;
+
+  *newsock = NULL;
+
+  status = apr_udp_connect(&csd, lr->sd, ptrans);
+  if (status == APR_SUCCESS) {
+    *newsock = csd;
+    apr_os_sock_get(&sockdes, csd);
+    if (sockdes >= FD_SETSIZE) {
+      ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_WARNING, 0, NULL,
+                         "new file descriptor %d is too large; you probably need "
+                         "to rebuild Apache with a larger FD_SETSIZE "
+                   "(currently %d)", sockdes, FD_SETSIZE);
+      apr_socket_close(csd);
+      return APR_EINTR;
+    }
+    return status;
+  }
+
+  ap_log_error(APLOG_MARK, APLOG_ERR, status, ap_server_conf,
+               "apr_udp_connect: (client socket)");
+  return APR_EGENERAL;
+  return status;
+}
+
+
Index: httpd-2.0/os/unix/unixd.h
===================================================================
RCS file: /home/cvspublic/httpd-2.0/os/unix/unixd.h,v
retrieving revision 1.36
diff -u -r1.36 unixd.h
--- httpd-2.0/os/unix/unixd.h	6 May 2002 18:19:53 -0000	1.36
+++ httpd-2.0/os/unix/unixd.h	13 Aug 2002 22:04:08 -0000
@@ -123,6 +123,12 @@
 AP_DECLARE(apr_status_t) unixd_set_proc_mutex_perms(apr_proc_mutex_t *pmutex);
 AP_DECLARE(apr_status_t) unixd_set_global_mutex_perms(apr_global_mutex_t *gmutex);
 AP_DECLARE(apr_status_t) unixd_accept(void **accepted, ap_listen_rec *lr, apr_pool_t *ptrans);
+AP_DECLARE(apr_status_t) unixd_pop_socket(void **sock, ap_listen_rec * lr,
+                                          apr_pool_t * ptrans);
+AP_DECLARE(apr_status_t) unixd_udp_connect(void **sock, ap_listen_rec * lr,
+                                           apr_pool_t * ptrans);
+
+
 
 #ifdef HAVE_KILLPG
 #define unixd_killpg(x, y)	(killpg ((x), (y)))
Index: httpd-2.0/server/connection.c
===================================================================
RCS file: /home/cvspublic/httpd-2.0/server/connection.c,v
retrieving revision 1.106
diff -u -r1.106 connection.c
--- httpd-2.0/server/connection.c	15 Jul 2002 08:05:10 -0000	1.106
+++ httpd-2.0/server/connection.c	13 Aug 2002 22:04:08 -0000
@@ -138,6 +138,7 @@
     apr_int32_t timeout;
     apr_int32_t total_linger_time = 0;
     apr_socket_t *csd = ap_get_module_config(c->conn_config, &core_module);
+    int socktype;
 
     if (!csd) {
         return;
@@ -164,32 +165,39 @@
         return;
     }
 
-    /* Shut down the socket for write, which will send a FIN
-     * to the peer.
+    /* For DGRAM sockets, there's no connection to shutdown, so we skip 
+     * all of the shutdown/so_linger code.
      */
-    if (apr_shutdown(csd, APR_SHUTDOWN_WRITE) != APR_SUCCESS
-        || c->aborted) {
-        apr_socket_close(csd);
-        return;
-    }
+    apr_os_sock_get_type(&socktype, csd);
+    if (socktype != SOCK_DGRAM) {
 
-    /* Read all data from the peer until we reach "end-of-file" (FIN
-     * from peer) or we've exceeded our overall timeout. If the client does
-     * not send us bytes within 2 seconds (a value pulled from Apache 1.3
-     * which seems to work well), close the connection.
-     */
-    timeout = apr_time_from_sec(SECONDS_TO_LINGER);
-    apr_socket_timeout_set(csd, timeout);
-    apr_socket_opt_set(csd, APR_INCOMPLETE_READ, 1);
-    while (1) {
-        nbytes = sizeof(dummybuf);
-        rc = apr_recv(csd, dummybuf, &nbytes);
-        if (rc != APR_SUCCESS || nbytes == 0)
-            break;
-
-        total_linger_time += SECONDS_TO_LINGER;
-        if (total_linger_time >= MAX_SECS_TO_LINGER) {
-            break;
+        /* Shut down the socket for write, which will send a FIN
+         * to the peer.
+         */
+        if (apr_shutdown(csd, APR_SHUTDOWN_WRITE) != APR_SUCCESS
+            || c->aborted) {
+            apr_socket_close(csd);
+            return;
+        }
+
+        /* Read all data from the peer until we reach "end-of-file" (FIN
+         * from peer) or we've exceeded our overall timeout. If the client does
+         * not send us bytes within 2 seconds (a value pulled from Apache 1.3
+         * which seems to work well), close the connection.
+         */
+        timeout = apr_time_from_sec(SECONDS_TO_LINGER);
+        apr_socket_timeout_set(csd, timeout);
+        apr_socket_opt_set(csd, APR_INCOMPLETE_READ, 1);
+        while (1) {
+            nbytes = sizeof(dummybuf);
+            rc = apr_recv(csd, dummybuf, &nbytes);
+            if (rc != APR_SUCCESS || nbytes == 0)
+                break;
+
+            total_linger_time += SECONDS_TO_LINGER;
+            if (total_linger_time >= MAX_SECS_TO_LINGER) {
+                break;
+            }
         }
     }
 
Index: httpd-2.0/server/core.c
===================================================================
RCS file: /home/cvspublic/httpd-2.0/server/core.c,v
retrieving revision 1.198
diff -u -r1.198 core.c
--- httpd-2.0/server/core.c	6 Aug 2002 20:02:07 -0000	1.198
+++ httpd-2.0/server/core.c	13 Aug 2002 22:04:08 -0000
@@ -2774,7 +2774,7 @@
     apr_int32_t i;
     apr_off_t o;             /* Track the file offset for partial writes */
     char buffer[8192];
-
+    apr_sockaddr_t *sa = NULL;
     *nbytes = 0;
 
     /* Send the headers
@@ -2798,6 +2798,12 @@
         rv = apr_file_seek(fd, APR_SET, &offset);
     }
 
+    /* get the remote address, so that we can use 
+    * connection-less & connection oriented sockets
+    * (ie UDP & TCP).
+    */
+    apr_socket_addr_get(&sa, APR_REMOTE, c->client_socket);
+
     /* Send the file, making sure to handle partial writes */
     togo = length;
     while (rv == APR_SUCCESS && togo) {
@@ -2806,7 +2812,8 @@
         rv = apr_file_read(fd, buffer, &sendlen);
         while (rv == APR_SUCCESS && sendlen) {
             bytes_sent = sendlen;
-            rv = apr_send(c->client_socket, &buffer[o], &bytes_sent);
+            rv = apr_sendto(c->client_socket, sa,
+                            0, &buffer[o], &bytes_sent);
             if (rv == APR_SUCCESS) {
                 sendlen -= bytes_sent; /* sendlen != bytes_sent ==> partial write */
                 o += bytes_sent;       /* o is where we are in the buffer */
@@ -3828,6 +3835,7 @@
 
         if (fd) {
             apr_hdtr_t hdtr;
+            int type;
 #if APR_HAS_SENDFILE
             apr_int32_t flags = 0;
 #endif
@@ -3849,22 +3857,31 @@
                 flags |= APR_SENDFILE_DISCONNECT_SOCKET;
             }
 
-            rv = sendfile_it_all(net,      /* the network information   */
-                                 fd,       /* the file to send          */
-                                 &hdtr,    /* header and trailer iovecs */
-                                 foffset,  /* offset in the file to begin
-                                              sending from              */
-                                 flen,     /* length of file            */
-                                 nbytes + flen, /* total length including
-                                                   headers                */
-                                 flags);   /* apr_sendfile flags        */
+            
+            /* connectionless UDP sockets cannot use sendfile(), so
+             * we'll bypass it and use the emulate_sendfile instead
+             * (which calls writev_it_all internally).
+             */
+            
+            apr_os_sock_get_type(&type, net->client_socket);
+            if (type == SOCK_STREAM) {
+              rv = sendfile_it_all(net,      /* the network information   */
+                                   fd,       /* the file to send          */
+                                   &hdtr,    /* header and trailer iovecs */
+                                   foffset,  /* offset in the file to begin
+                                                sending from              */
+                                   flen,     /* length of file            */
+                                   nbytes + flen, /* total length including
+                                                     headers                */
+                                   flags);   /* apr_sendfile flags        */
+            }
 
             /* If apr_sendfile() returns APR_ENOTIMPL, call emulate_sendfile().
              * emulate_sendfile() is useful to enable the same Apache binary
              * distribution to support Windows NT/2000 (supports TransmitFile)
              * and Win95/98 (do not support TransmitFile)
              */
-            if (rv == APR_ENOTIMPL)
+            if (rv == APR_ENOTIMPL || type == SOCK_DGRAM)
 #endif
             {
                 apr_size_t unused_bytes_sent;
@@ -4061,6 +4078,7 @@
 static int core_pre_connection(conn_rec *c, void *csd)
 {
     core_net_rec *net = apr_palloc(c->pool, sizeof(*net));
+    int socktype;
 
 #ifdef AP_MPM_DISABLE_NAGLE_ACCEPTED_SOCK
     /* BillS says perhaps this should be moved to the MPMs. Some OSes
@@ -4068,7 +4086,10 @@
      * accept sockets which means this call only needs to be made
      * once on the listener
      */
-    ap_sock_disable_nagle(csd);
+    apr_os_sock_get_type(&socktype, csd);
+    if (socktype != SOCK_DGRAM) {
+      ap_sock_disable_nagle(csd);
+    }
 #endif
     net->c = c;
     net->in_ctx = NULL;
Index: httpd-2.0/server/listen.c
===================================================================
RCS file: /home/cvspublic/httpd-2.0/server/listen.c,v
retrieving revision 1.82
diff -u -r1.82 listen.c
--- httpd-2.0/server/listen.c	31 Jul 2002 12:44:55 -0000	1.82
+++ httpd-2.0/server/listen.c	13 Aug 2002 22:04:08 -0000
@@ -89,6 +89,7 @@
     apr_socket_t *s = server->sd;
     int one = 1;
     apr_status_t stat;
+    int socktype;
 
 #ifndef WIN32
     stat = apr_socket_opt_set(s, APR_SO_REUSEADDR, one);
@@ -140,10 +141,6 @@
         }
     }
 
-#if APR_TCP_NODELAY_INHERITED
-    ap_sock_disable_nagle(s);
-#endif
-
     if ((stat = apr_bind(s, server->bind_addr)) != APR_SUCCESS) {
         ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, stat, p,
                       "make_sock: could not bind to address %pI",
@@ -152,13 +149,31 @@
         return stat;
     }
 
-    if ((stat = apr_listen(s, ap_listenbacklog)) != APR_SUCCESS) {
+    /* if UDP, we ignore the Nagle algorithm for UDP.
+     * We also forgo listening, since UDP has no
+     * notion of listening sockets.
+     */
+    apr_os_sock_get_type(&socktype, s);
+
+    if (socktype != SOCK_DGRAM) {
+#if APR_TCP_NODELAY_INHERITED
+      ap_sock_disable_nagle(s);
+#endif
+
+      if ((stat = apr_listen(s, ap_listenbacklog)) != APR_SUCCESS) {
         ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_ERR, stat, p,
                       "make_sock: unable to listen for connections "
                       "on address %pI",
                       server->bind_addr);
         apr_socket_close(s);
         return stat;
+      }
+#if APR_HAS_SO_ACCEPTFILTER
+#ifndef ACCEPT_FILTER_NAME
+#define ACCEPT_FILTER_NAME "dataready"
+#endif
+      apr_socket_accept_filter(s, ACCEPT_FILTER_NAME, "");
+#endif
     }
 
 #ifdef WIN32
@@ -246,7 +261,8 @@
 }
 
 
-static const char *alloc_listener(process_rec *process, char *addr, apr_port_t port)
+static const char *alloc_listener(process_rec *process, char *addr, 
+                                  apr_port_t port, int transport_type)
 {
     ap_listen_rec **walk;
     ap_listen_rec *new;
@@ -302,7 +318,7 @@
     }
     if ((status = apr_socket_create(&new->sd,
                                     new->bind_addr->family,
-                                    SOCK_STREAM, process->pool))
+                                    transport_type, process->pool))
         != APR_SUCCESS) {
         ap_log_perror(APLOG_MARK, APLOG_CRIT, status, process->pool,
                       "alloc_listener: failed to get a socket for %s", addr);
@@ -384,6 +400,7 @@
     char *host, *scope_id;
     apr_port_t port;
     apr_status_t rv;
+    int transport_type = (int)cmd->cmd->cmd_data;
     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
 
     if (err != NULL) {
@@ -408,7 +425,7 @@
         return "Port must be specified";
     }
 
-    return alloc_listener(cmd->server->process, host, port);
+    return alloc_listener(cmd->server->process, host, port, transport_type);
 }
 
 const char *ap_set_listenbacklog(cmd_parms *cmd, void *dummy, const char *arg)
Index: httpd-2.0/server/main.c
===================================================================
RCS file: /home/cvspublic/httpd-2.0/server/main.c,v
retrieving revision 1.137
diff -u -r1.137 main.c
--- httpd-2.0/server/main.c	17 Jul 2002 07:10:52 -0000	1.137
+++ httpd-2.0/server/main.c	13 Aug 2002 22:04:09 -0000
@@ -408,11 +408,13 @@
     apr_status_t rv;
     module **mod;
     const char *optarg;
+
     APR_OPTIONAL_FN_TYPE(ap_signal_server) *signal_server;
 
     AP_MONCONTROL(0); /* turn off profiling of startup */
 
     apr_app_initialize(&argc, &argv, NULL);
+
 
     process = create_process(argc, argv);
     pglobal = process->pool;
Index: httpd-2.0/server/mpm/experimental/leader/leader.c
===================================================================
RCS file: /home/cvspublic/httpd-2.0/server/mpm/experimental/leader/leader.c,v
retrieving revision 1.23
diff -u -r1.23 leader.c
--- httpd-2.0/server/mpm/experimental/leader/leader.c	11 Jul 2002 05:42:19 -0000	1.23
+++ httpd-2.0/server/mpm/experimental/leader/leader.c	13 Aug 2002 22:04:09 -0000
@@ -2068,6 +2068,7 @@
 static const command_rec leader_cmds[] = {
 UNIX_DAEMON_COMMANDS,
 LISTEN_COMMANDS,
+UDP_LISTEN_COMMANDS,
 AP_INIT_TAKE1("StartServers", set_daemons_to_start, NULL, RSRC_CONF,
   "Number of child processes launched at server startup"),
 AP_INIT_TAKE1("MinSpareThreads", set_min_spare_threads, NULL, RSRC_CONF,
Index: httpd-2.0/server/mpm/experimental/leader/mpm.h
===================================================================
RCS file: /home/cvspublic/httpd-2.0/server/mpm/experimental/leader/mpm.h,v
retrieving revision 1.5
diff -u -r1.5 mpm.h
--- httpd-2.0/server/mpm/experimental/leader/mpm.h	4 Jul 2002 15:20:53 -0000	1.5
+++ httpd-2.0/server/mpm/experimental/leader/mpm.h	13 Aug 2002 22:04:09 -0000
@@ -80,7 +80,7 @@
 #define AP_MPM_USES_POD 1
 #define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid)
 #define MPM_NOTE_CHILD_KILLED(i) (MPM_CHILD_PID(i) = 0)
-#define MPM_ACCEPT_FUNC unixd_accept
+#define MPM_ACCEPT_FUNC unixd_pop_socket
 
 extern int ap_threads_per_child;
 extern int ap_max_daemons_limit;
Index: httpd-2.0/server/mpm/experimental/perchild/mpm.h
===================================================================
RCS file: /home/cvspublic/httpd-2.0/server/mpm/experimental/perchild/mpm.h,v
retrieving revision 1.17
diff -u -r1.17 mpm.h
--- httpd-2.0/server/mpm/experimental/perchild/mpm.h	21 Jun 2002 11:00:43 -0000	1.17
+++ httpd-2.0/server/mpm/experimental/perchild/mpm.h	13 Aug 2002 22:04:09 -0000
@@ -81,7 +81,7 @@
 
 #define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid)
 #define MPM_NOTE_CHILD_KILLED(i) (MPM_CHILD_PID(i) = 0)
-#define MPM_ACCEPT_FUNC unixd_accept
+#define MPM_ACCEPT_FUNC unixd_pop_socket
 
 /* Table of child status */
 #define SERVER_DEAD 0
Index: httpd-2.0/server/mpm/experimental/perchild/perchild.c
===================================================================
RCS file: /home/cvspublic/httpd-2.0/server/mpm/experimental/perchild/perchild.c,v
retrieving revision 1.130
diff -u -r1.130 perchild.c
--- httpd-2.0/server/mpm/experimental/perchild/perchild.c	17 Jul 2002 18:44:43 -0000	1.130
+++ httpd-2.0/server/mpm/experimental/perchild/perchild.c	13 Aug 2002 22:04:09 -0000
@@ -1998,6 +1998,7 @@
 static const command_rec perchild_cmds[] = {
 UNIX_DAEMON_COMMANDS,
 LISTEN_COMMANDS,
+UDP_LISTEN_COMMANDS,
 AP_INIT_TAKE1("NumServers", set_num_daemons, NULL, RSRC_CONF,
               "Number of children alive at the same time"),
 AP_INIT_TAKE1("StartThreads", set_threads_to_start, NULL, RSRC_CONF,
Index: httpd-2.0/server/mpm/prefork/mpm.h
===================================================================
RCS file: /home/cvspublic/httpd-2.0/server/mpm/prefork/mpm.h,v
retrieving revision 1.21
diff -u -r1.21 mpm.h
--- httpd-2.0/server/mpm/prefork/mpm.h	4 Jul 2002 15:20:54 -0000	1.21
+++ httpd-2.0/server/mpm/prefork/mpm.h	13 Aug 2002 22:04:09 -0000
@@ -84,7 +84,7 @@
 #define AP_MPM_USES_POD 1
 #define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid)
 #define MPM_NOTE_CHILD_KILLED(i) (MPM_CHILD_PID(i) = 0)
-#define MPM_ACCEPT_FUNC unixd_accept
+#define MPM_ACCEPT_FUNC unixd_pop_socket
 
 extern int ap_threads_per_child;
 extern int ap_max_daemons_limit;
Index: httpd-2.0/server/mpm/prefork/prefork.c
===================================================================
RCS file: /home/cvspublic/httpd-2.0/server/mpm/prefork/prefork.c,v
retrieving revision 1.271
diff -u -r1.271 prefork.c
--- httpd-2.0/server/mpm/prefork/prefork.c	17 Jul 2002 21:39:55 -0000	1.271
+++ httpd-2.0/server/mpm/prefork/prefork.c	13 Aug 2002 22:04:09 -0000
@@ -1400,6 +1400,7 @@
 static const command_rec prefork_cmds[] = {
 UNIX_DAEMON_COMMANDS,
 LISTEN_COMMANDS,
+UDP_LISTEN_COMMANDS,
 AP_INIT_TAKE1("StartServers", set_daemons_to_start, NULL, RSRC_CONF,
               "Number of child processes launched at server startup"),
 AP_INIT_TAKE1("MinSpareServers", set_min_free_servers, NULL, RSRC_CONF,
Index: httpd-2.0/server/mpm/worker/mpm.h
===================================================================
RCS file: /home/cvspublic/httpd-2.0/server/mpm/worker/mpm.h,v
retrieving revision 1.14
diff -u -r1.14 mpm.h
--- httpd-2.0/server/mpm/worker/mpm.h	4 Jul 2002 15:20:54 -0000	1.14
+++ httpd-2.0/server/mpm/worker/mpm.h	13 Aug 2002 22:04:09 -0000
@@ -80,7 +80,7 @@
 
 #define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid)
 #define MPM_NOTE_CHILD_KILLED(i) (MPM_CHILD_PID(i) = 0)
-#define MPM_ACCEPT_FUNC unixd_accept
+#define MPM_ACCEPT_FUNC unixd_pop_socket
 
 extern int ap_threads_per_child;
 extern int ap_max_daemons_limit;
Index: httpd-2.0/server/mpm/worker/worker.c
===================================================================
RCS file: /home/cvspublic/httpd-2.0/server/mpm/worker/worker.c,v
retrieving revision 1.131
diff -u -r1.131 worker.c
--- httpd-2.0/server/mpm/worker/worker.c	11 Jul 2002 05:42:20 -0000	1.131
+++ httpd-2.0/server/mpm/worker/worker.c	13 Aug 2002 22:04:09 -0000
@@ -2156,6 +2156,7 @@
 static const command_rec worker_cmds[] = {
 UNIX_DAEMON_COMMANDS,
 LISTEN_COMMANDS,
+UDP_LISTEN_COMMANDS,
 AP_INIT_TAKE1("StartServers", set_daemons_to_start, NULL, RSRC_CONF,
   "Number of child processes launched at server startup"),
 AP_INIT_TAKE1("MinSpareThreads", set_min_spare_threads, NULL, RSRC_CONF,
Index: httpd-2.0/srclib/apr/network_io/unix/sendrecv.c
===================================================================
RCS file: /home/cvspublic/apr/network_io/unix/sendrecv.c,v
retrieving revision 1.88
diff -u -r1.88 sendrecv.c
--- httpd-2.0/srclib/apr/network_io/unix/sendrecv.c	15 Jul 2002 07:56:13 -0000	1.88
+++ httpd-2.0/srclib/apr/network_io/unix/sendrecv.c	13 Aug 2002 22:04:09 -0000
@@ -221,6 +221,27 @@
     apr_ssize_t rv;
     apr_size_t requested_len = 0;
     apr_int32_t i;
+    int socktype;
+    struct msghdr msg;
+    apr_sockaddr_t *sa = NULL;
+
+    /* unconditionally using sendmsg, to support UDP as well
+     * as TCP.  No longer using writev.
+     */
+
+    memset(&msg, 0, sizeof(msg));
+    /* this is UDP, so we need to extract the remote address
+     * that we're going to write the packet to.  This
+     * remote address was filled in on the recvfrom() 
+     * call.
+     */
+    apr_socket_addr_get(&sa, APR_REMOTE, sock);
+
+    /* fill in the msghdr, needed by sendmsg */
+    msg.msg_name = (void *) &sa->sa;
+    msg.msg_namelen = sizeof(const struct sockaddr);
+    msg.msg_iov = (struct iovec *) vec;
+    msg.msg_iovlen = nvec;
 
     for (i = 0; i < nvec; i++) {
         requested_len += vec[i].iov_len;
@@ -232,7 +253,7 @@
     }
 
     do {
-        rv = writev(sock->socketdes, vec, nvec);
+        rv = sendmsg(sock->socketdes, &msg, 0);
     } while (rv == -1 && errno == EINTR);
 
     if (rv == -1 && (errno == EAGAIN || errno == EWOULDBLOCK) && 
@@ -803,6 +824,7 @@
         sock->netmask &= ~APR_INCOMPLETE_WRITE;
         goto do_select;
     }
+
 
     do {
         rv = send_file(&(sock->socketdes), /* socket */
Index: httpd-2.0/srclib/apr/network_io/unix/sockets.c
===================================================================
RCS file: /home/cvspublic/apr/network_io/unix/sockets.c,v
retrieving revision 1.101
diff -u -r1.101 sockets.c
--- httpd-2.0/srclib/apr/network_io/unix/sockets.c	30 Jul 2002 13:56:14 -0000	1.101
+++ httpd-2.0/srclib/apr/network_io/unix/sockets.c	13 Aug 2002 22:04:09 -0000
@@ -368,6 +368,37 @@
     return APR_SUCCESS;
 }
 
+apr_status_t apr_udp_connect(apr_socket_t ** new, 
+                             apr_socket_t * sock,
+                             apr_pool_t * connection_context)
+{
+  alloc_socket(new, connection_context);
+
+  set_socket_vars(*new, AF_INET, SOCK_DGRAM);
+  (*new)->timeout = -1;
+
+  /* dup the socket, so that we may later close it */
+  (*new)->socketdes = fcntl(sock->socketdes, F_DUPFD);
+  if ((*new)->socketdes < 0) {
+    return errno;
+  }
+
+  apr_pool_cleanup_register((*new)->cntxt, (void *) (*new), socket_cleanup,
+                            socket_cleanup);
+
+  return APR_SUCCESS;
+}
+
+apr_status_t apr_os_sock_get_type(int *socktype, 
+                                  apr_socket_t * sock)
+{
+  *socktype = sock->type;
+  return APR_SUCCESS;
+}
+
+
 APR_IMPLEMENT_INHERIT_SET(socket, inherit, cntxt, socket_cleanup)
 
 APR_IMPLEMENT_INHERIT_UNSET(socket, inherit, cntxt, socket_cleanup)
+
+
Index: httpd-2.0/srclib/apr-util/buckets/apr_buckets_socket.c
===================================================================
RCS file: /home/cvspublic/apr-util/buckets/apr_buckets_socket.c,v
retrieving revision 1.43
diff -u -r1.43 apr_buckets_socket.c
--- httpd-2.0/srclib/apr-util/buckets/apr_buckets_socket.c	16 Jul 2002 05:50:39 -0000	1.43
+++ httpd-2.0/srclib/apr-util/buckets/apr_buckets_socket.c	13 Aug 2002 22:04:09 -0000
@@ -61,6 +61,7 @@
     char *buf;
     apr_status_t rv;
     apr_interval_time_t timeout;
+    apr_sockaddr_t *sa = NULL;
 
     if (block == APR_NONBLOCK_READ) {
         apr_socket_timeout_get(p, &timeout);
@@ -71,7 +72,8 @@
     *len = APR_BUCKET_BUFF_SIZE;
     buf = apr_bucket_alloc(*len, a->list); /* XXX: check for failure? */
 
-    rv = apr_recv(p, buf, len);
+    apr_socket_addr_get(&sa, APR_REMOTE, p);
+    rv = apr_recvfrom(sa, p, 0,buf, len);
 
     if (block == APR_NONBLOCK_READ) {
         apr_socket_timeout_set(p, timeout);
