2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 #include <afsconfig.h>
11 #include "../afs/param.h"
15 #include "../rx/rx_kcommon.h"
17 int osi_NetReceive(asocket, addr, dvec, nvecs, alength)
18 struct socket *asocket;
19 struct sockaddr_in *addr;
26 struct iovec iov[RX_MAXIOVECS];
30 int haveGlock = ISAFS_GLOCK();
31 /*AFS_STATCNT(osi_NetReceive);*/
33 if (nvecs > RX_MAXIOVECS) {
34 osi_Panic("osi_NetReceive: %d: Too many iovecs.\n", nvecs);
37 for (i = 0 ; i < nvecs ; i++) {
38 iov[i].iov_base = dvec[i].iov_base;
39 iov[i].iov_len = dvec[i].iov_len;
46 u.uio_segflg=UIO_SYSSPACE;
53 #if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL)
54 thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
56 code = soreceive(asocket, &sa, &u, NULL, NULL, NULL);
57 #if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL)
58 thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL);
63 *alength=*alength-u.uio_resid;
65 if (sa->sa_family == AF_INET) {
66 if (addr) *addr=*(struct sockaddr_in *)sa;
68 printf("Unknown socket family %d in NetReceive\n");
74 extern int rxk_ListenerPid;
75 void osi_StopListener(void)
79 #if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL)
80 thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
83 #if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL)
84 thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL);
86 p=pfind(rxk_ListenerPid);
91 /* rx_NetSend - send asize bytes at adata from asocket to host at addr.
93 * Now, why do we allocate a new buffer when we could theoretically use the one
94 * pointed to by adata? Because PRU_SEND returns after queueing the message,
95 * not after sending it. If the sender changes the data after queueing it,
96 * we'd see the already-queued data change. One attempt to fix this without
97 * adding a copy would be to have this function wait until the datagram is
98 * sent; however this doesn't work well. In particular, if a host is down, and
99 * an ARP fails to that host, this packet will be queued until the ARP request
100 * comes back, which could be hours later. We can't block in this routine that
101 * long, since it prevents RPC timeouts from happening.
103 /* XXX In the brave new world, steal the data bufs out of the rx_packet iovec,
104 * and just queue those. XXX
109 osi_NetSend(asocket, addr, dvec, nvecs, alength, istack)
110 register struct socket *asocket;
113 register afs_int32 alength;
114 struct sockaddr_in *addr;
117 register afs_int32 code;
121 struct iovec iov[RX_MAXIOVECS];
125 int haveGlock = ISAFS_GLOCK();
127 AFS_STATCNT(osi_NetSend);
128 if (nvecs > RX_MAXIOVECS) {
129 osi_Panic("osi_NetSend: %d: Too many iovecs.\n", nvecs);
132 for (i = 0 ; i < nvecs ; i++) {
133 iov[i].iov_base = dvec[i].iov_base;
134 iov[i].iov_len = dvec[i].iov_len;
141 u.uio_segflg=UIO_SYSSPACE;
147 #if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL)
148 thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
150 nam=m_get(M_DONTWAIT, MT_SONAME);
155 nam->m_len=addr->sin_len=sizeof(struct sockaddr_in);
156 memcpy(mtod(nam, caddr_t), (caddr_t)addr, addr->sin_len);
157 code = sosend(asocket, mtod(nam, struct sockaddr *), &u, NULL, NULL, 0);
160 #if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL)
161 thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL);