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