Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / rx / OBSD / rx_knet.c
1 /*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
4 *
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
8 */
9
10 #include <afsconfig.h>
11 #include "../afs/param.h"
12
13
14 #include "../rx/rx_kcommon.h"
15
16 int
17 osi_NetReceive(osi_socket asocket, struct sockaddr_in *addr,
18 struct iovec *dvec, int nvecs, int *alength)
19 {
20 struct uio u;
21 int i, code;
22 struct iovec iov[RX_MAXIOVECS];
23 struct mbuf *nam = NULL;
24
25 int haveGlock = ISAFS_GLOCK();
26
27 memset(&u, 0, sizeof(u));
28 memset(&iov, 0, sizeof(iov));
29
30 if (nvecs > RX_MAXIOVECS)
31 osi_Panic("osi_NetReceive: %d: too many iovecs\n", nvecs);
32
33 for (i = 0; i < nvecs; i++)
34 iov[i] = dvec[i];
35
36 u.uio_iov = &iov[0];
37 u.uio_iovcnt = nvecs;
38 u.uio_offset = 0;
39 u.uio_resid = *alength;
40 u.uio_segflg = UIO_SYSSPACE;
41 u.uio_rw = UIO_READ;
42 u.uio_procp = NULL;
43
44 if (haveGlock)
45 AFS_GUNLOCK();
46 code = soreceive(asocket, (addr ? &nam : NULL), &u, NULL, NULL, NULL
47 #if defined(AFS_OBSD45_ENV)
48 , 0
49 #endif
50 );
51 if (haveGlock)
52 AFS_GLOCK();
53
54 if (code) {
55 #ifdef RXKNET_DEBUG
56 printf("rx code %d termState %d\n", code, afs_termState);
57 #endif
58 while (afs_termState == AFSOP_STOP_RXEVENT)
59 afs_osi_Sleep(&afs_termState);
60 return code;
61 }
62
63 *alength -= u.uio_resid;
64 if (addr && nam) {
65 memcpy(addr, mtod(nam, caddr_t), nam->m_len);
66 m_freem(nam);
67 }
68
69 return code;
70 }
71
72 extern int rxk_ListenerPid;
73 void
74 osi_StopListener(void)
75 {
76 struct proc *p;
77
78 soclose(rx_socket);
79 p = pfind(rxk_ListenerPid);
80 if (p)
81 psignal(p, SIGUSR1);
82 }
83
84 /*
85 * rx_NetSend - send asize bytes at adata from asocket to host at addr.
86 */
87
88 int
89 osi_NetSend(osi_socket asocket, struct sockaddr_in *addr, struct iovec *dvec,
90 int nvecs, afs_int32 alength, int istack)
91 {
92 int i, code;
93 struct iovec iov[RX_MAXIOVECS];
94 struct uio u;
95 struct mbuf *nam;
96 int haveGlock = ISAFS_GLOCK();
97
98 memset(&u, 0, sizeof(u));
99 memset(&iov, 0, sizeof(iov));
100
101 AFS_STATCNT(osi_NetSend);
102 if (nvecs > RX_MAXIOVECS)
103 osi_Panic("osi_NetSend: %d: Too many iovecs.\n", nvecs);
104
105 for (i = 0; i < nvecs; i++)
106 iov[i] = dvec[i];
107
108 u.uio_iov = &iov[0];
109 u.uio_iovcnt = nvecs;
110 u.uio_offset = 0;
111 u.uio_resid = alength;
112 u.uio_segflg = UIO_SYSSPACE;
113 u.uio_rw = UIO_WRITE;
114 u.uio_procp = NULL;
115
116 nam = m_get(M_DONTWAIT, MT_SONAME);
117 if (!nam)
118 return ENOBUFS;
119 nam->m_len = addr->sin_len = sizeof(struct sockaddr_in);
120 memcpy(mtod(nam, caddr_t), addr, addr->sin_len);
121
122 if (haveGlock)
123 AFS_GUNLOCK();
124 code = sosend(asocket, nam, &u, NULL, NULL, 0);
125 if (haveGlock)
126 AFS_GLOCK();
127 m_freem(nam);
128
129 return code;
130 }