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(osi_socket so, struct sockaddr_in *addr, struct iovec *dvec,
18 int nvecs, int *alength)
20 struct socket *asocket = (struct socket *)so;
23 struct iovec iov[RX_MAXIOVECS];
27 int haveGlock = ISAFS_GLOCK();
28 /*AFS_STATCNT(osi_NetReceive);*/
30 if (nvecs > RX_MAXIOVECS) {
31 osi_Panic("osi_NetReceive: %d: Too many iovecs.\n", nvecs);
34 for (i = 0 ; i < nvecs ; i++) {
35 iov[i].iov_base = dvec[i].iov_base;
36 iov[i].iov_len = dvec[i].iov_len;
43 u.uio_segflg=UIO_SYSSPACE;
50 #if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL)
51 thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
53 code = soreceive(asocket, &sa, &u, NULL, NULL, NULL);
54 #if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL)
55 thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL);
60 *alength=*alength-u.uio_resid;
62 if (sa->sa_family == AF_INET) {
63 if (addr) *addr=*(struct sockaddr_in *)sa;
65 printf("Unknown socket family %d in NetReceive\n");
71 extern int rxk_ListenerPid;
72 void osi_StopListener(void)
76 #if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL)
77 thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
80 #if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL)
81 thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL);
83 p=pfind(rxk_ListenerPid);
88 /* rx_NetSend - send asize bytes at adata from asocket to host at addr.
90 * Now, why do we allocate a new buffer when we could theoretically use the one
91 * pointed to by adata? Because PRU_SEND returns after queueing the message,
92 * not after sending it. If the sender changes the data after queueing it,
93 * we'd see the already-queued data change. One attempt to fix this without
94 * adding a copy would be to have this function wait until the datagram is
95 * sent; however this doesn't work well. In particular, if a host is down, and
96 * an ARP fails to that host, this packet will be queued until the ARP request
97 * comes back, which could be hours later. We can't block in this routine that
98 * long, since it prevents RPC timeouts from happening.
100 /* XXX In the brave new world, steal the data bufs out of the rx_packet iovec,
101 * and just queue those. XXX
106 osi_NetSend(osi_socket asocket, struct sockaddr_in *addr,
107 struct iovec *dvec, int nvecs, afs_int32 alength, int istack)
109 register afs_int32 code;
113 struct iovec iov[RX_MAXIOVECS];
117 int haveGlock = ISAFS_GLOCK();
119 AFS_STATCNT(osi_NetSend);
120 if (nvecs > RX_MAXIOVECS) {
121 osi_Panic("osi_NetSend: %d: Too many iovecs.\n", nvecs);
124 for (i = 0 ; i < nvecs ; i++) {
125 iov[i].iov_base = dvec[i].iov_base;
126 iov[i].iov_len = dvec[i].iov_len;
133 u.uio_segflg=UIO_SYSSPACE;
139 #if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL)
140 thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
142 nam=m_get(M_DONTWAIT, MT_SONAME);
147 nam->m_len=addr->sin_len=sizeof(struct sockaddr_in);
148 memcpy(mtod(nam, caddr_t), (caddr_t)addr, addr->sin_len);
149 code = sosend(asocket, mtod(nam, struct sockaddr *), &u, NULL, NULL, 0);
152 #if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL)
153 thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL);