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