Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / rx / NBSD / 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 glocked = 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 UIO_SETUP_SYSSPACE(&u);
41 u.uio_rw = UIO_READ;
42 #if 0
43 u.uio_procp = NULL;
44 #endif
45 if (glocked)
46 AFS_GUNLOCK();
47 code = soreceive(asocket, (addr ? &nam : NULL), &u, NULL, NULL, NULL);
48 if (glocked)
49 AFS_GLOCK();
50
51 if (code) {
52 #ifdef RXKNET_DEBUG
53 printf("rx code %d termState %d\n", code, afs_termState);
54 #endif
55 while (afs_termState == AFSOP_STOP_RXEVENT)
56 afs_osi_Sleep(&afs_termState);
57 return code;
58 }
59
60 *alength -= u.uio_resid;
61 if (addr && nam) {
62 memcpy(addr, mtod(nam, caddr_t), nam->m_len);
63 m_freem(nam);
64 }
65
66 return code;
67 }
68
69 extern int rxk_ListenerPid;
70 void
71 osi_StopListener(void)
72 {
73 struct proc *p;
74
75 solock(rx_socket);
76 soshutdown(rx_socket, SHUT_RDWR);
77 sounlock(rx_socket);
78 mutex_enter(proc_lock);
79 p = proc_find(rxk_ListenerPid);
80 mutex_exit(proc_lock);
81 if (p)
82 psignal(p, SIGUSR1);
83 soclose(rx_socket);
84 }
85
86 /*
87 * rx_NetSend - send asize bytes at adata from asocket to host at addr.
88 */
89
90 int
91 osi_NetSend(osi_socket asocket, struct sockaddr_in *addr, struct iovec *dvec,
92 int nvecs, afs_int32 alength, int istack)
93 {
94 int i, code;
95 struct iovec iov[RX_MAXIOVECS];
96 struct uio u;
97 struct mbuf *nam;
98 int glocked = ISAFS_GLOCK();
99
100 memset(&u, 0, sizeof(u));
101 memset(&iov, 0, sizeof(iov));
102
103 AFS_STATCNT(osi_NetSend);
104 if (nvecs > RX_MAXIOVECS)
105 osi_Panic("osi_NetSend: %d: Too many iovecs.\n", nvecs);
106
107 for (i = 0; i < nvecs; i++)
108 iov[i] = dvec[i];
109
110 u.uio_iov = &iov[0];
111 u.uio_iovcnt = nvecs;
112 u.uio_offset = 0;
113 u.uio_resid = alength;
114 UIO_SETUP_SYSSPACE(&u);
115 u.uio_rw = UIO_WRITE;
116 #if 0
117 u.uio_procp = NULL;
118 #endif
119 nam = m_get(M_DONTWAIT, MT_SONAME);
120 if (!nam)
121 return ENOBUFS;
122 nam->m_len = addr->sin_len = sizeof(struct sockaddr_in);
123 memcpy(mtod(nam, caddr_t), addr, addr->sin_len);
124
125 if (glocked)
126 AFS_GUNLOCK();
127 code = sosend(asocket, nam, &u, NULL, NULL, 0, osi_curproc());
128 if (glocked)
129 AFS_GLOCK();
130 m_freem(nam);
131
132 return code;
133 }