death to register
[openafs.git] / src / rx / DARWIN / 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 #ifdef AFS_DARWIN80_ENV
17 #define soclose sock_close
18 #endif
19  
20 int
21 osi_NetReceive(osi_socket so, struct sockaddr_in *addr, struct iovec *dvec,
22                int nvecs, int *alength)
23 {
24 #ifdef AFS_DARWIN80_ENV
25     socket_t asocket = (socket_t)so;
26     struct msghdr msg;
27     struct sockaddr_storage ss;
28     int rlen;
29     mbuf_t m;
30 #else
31     struct socket *asocket = (struct socket *)so;
32     struct uio u;
33 #endif
34     int i;
35     struct iovec iov[RX_MAXIOVECS];
36     struct sockaddr *sa = NULL;
37     int code;
38     size_t resid;
39
40     int haveGlock = ISAFS_GLOCK();
41     /*AFS_STATCNT(osi_NetReceive); */
42
43     if (nvecs > RX_MAXIOVECS)
44         osi_Panic("osi_NetReceive: %d: Too many iovecs.\n", nvecs);
45
46     for (i = 0; i < nvecs; i++)
47         iov[i] = dvec[i];
48
49     if ((afs_termState == AFSOP_STOP_RXK_LISTENER) ||
50         (afs_termState == AFSOP_STOP_COMPLETE))
51         return -1;
52
53     if (haveGlock)
54         AFS_GUNLOCK();
55 #if defined(KERNEL_FUNNEL)
56     thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
57 #endif
58 #ifdef AFS_DARWIN80_ENV
59     resid = *alength;
60     memset(&msg, 0, sizeof(struct msghdr));
61     msg.msg_name = &ss;
62     msg.msg_namelen = sizeof(struct sockaddr_storage);
63     sa =(struct sockaddr *) &ss;
64     code = sock_receivembuf(asocket, &msg, &m, 0, alength);
65     if (!code) {
66         size_t offset=0,sz;
67         resid = *alength;
68         for (i=0;i<nvecs && resid;i++) {
69             sz=MIN(resid, iov[i].iov_len);
70             code = mbuf_copydata(m, offset, sz, iov[i].iov_base);
71             if (code)
72                 break;
73             resid-=sz;
74             offset+=sz;
75         }
76     }
77     mbuf_freem(m);
78 #else
79
80     u.uio_iov = &iov[0];
81     u.uio_iovcnt = nvecs;
82     u.uio_offset = 0;
83     u.uio_resid = *alength;
84     u.uio_segflg = UIO_SYSSPACE;
85     u.uio_rw = UIO_READ;
86     u.uio_procp = NULL;
87     code = soreceive(asocket, &sa, &u, NULL, NULL, NULL);
88     resid = u.uio_resid;
89 #endif
90
91 #if defined(KERNEL_FUNNEL)
92     thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL);
93 #endif
94     if (haveGlock)
95         AFS_GLOCK();
96
97     if (code)
98         return code;
99     *alength -= resid;
100     if (sa) {
101         if (sa->sa_family == AF_INET) {
102             if (addr)
103                 *addr = *(struct sockaddr_in *)sa;
104         } else
105             printf("Unknown socket family %d in NetReceive\n", sa->sa_family);
106 #ifndef AFS_DARWIN80_ENV
107         FREE(sa, M_SONAME);
108 #endif
109     }
110     return code;
111 }
112
113 extern int rxk_ListenerPid;
114 void
115 osi_StopListener(void)
116 {
117     struct proc *p;
118
119 #if defined(KERNEL_FUNNEL)
120     thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
121 #endif
122     soclose(rx_socket);
123 #if defined(KERNEL_FUNNEL)
124     thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL);
125 #endif
126 #ifndef AFS_DARWIN80_ENV
127     p = pfind(rxk_ListenerPid);
128     if (p)
129         psignal(p, SIGUSR1);
130 #endif
131 }
132
133 int
134 osi_NetSend(osi_socket so, struct sockaddr_in *addr, struct iovec *dvec,
135             int nvecs, afs_int32 alength, int istack)
136 {
137 #ifdef AFS_DARWIN80_ENV
138     socket_t asocket = (socket_t)so;
139     struct msghdr msg;
140     size_t slen;
141 #else
142     struct socket *asocket = (struct socket *)so;
143     struct uio u;
144 #endif
145     afs_int32 code;
146     int i;
147     struct iovec iov[RX_MAXIOVECS];
148     int haveGlock = ISAFS_GLOCK();
149
150     AFS_STATCNT(osi_NetSend);
151     if (nvecs > RX_MAXIOVECS)
152         osi_Panic("osi_NetSend: %d: Too many iovecs.\n", nvecs);
153
154     for (i = 0; i < nvecs; i++)
155         iov[i] = dvec[i];
156
157     addr->sin_len = sizeof(struct sockaddr_in);
158
159     if ((afs_termState == AFSOP_STOP_RXK_LISTENER) ||
160         (afs_termState == AFSOP_STOP_COMPLETE))
161         return -1;
162
163     if (haveGlock)
164         AFS_GUNLOCK();
165
166 #if defined(KERNEL_FUNNEL)
167     thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
168 #endif
169 #ifdef AFS_DARWIN80_ENV
170     memset(&msg, 0, sizeof(struct msghdr));
171     msg.msg_name = addr;
172     msg.msg_namelen = ((struct sockaddr *)addr)->sa_len;
173     msg.msg_iov = &iov[0];
174     msg.msg_iovlen = nvecs;
175     code = sock_send(asocket, &msg, 0, &slen);
176 #else
177     u.uio_iov = &iov[0];
178     u.uio_iovcnt = nvecs;
179     u.uio_offset = 0;
180     u.uio_resid = alength;
181     u.uio_segflg = UIO_SYSSPACE;
182     u.uio_rw = UIO_WRITE;
183     u.uio_procp = NULL;
184     code = sosend(asocket, (struct sockaddr *)addr, &u, NULL, NULL, 0);
185 #endif
186
187 #if defined(KERNEL_FUNNEL)
188     thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL);
189 #endif
190     if (haveGlock)
191         AFS_GLOCK();
192     return code;
193 }