fix-netreceive-memleak-20030130
[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 RCSID("$Header$");
14
15 #include "../rx/rx_kcommon.h"
16
17 int osi_NetReceive(osi_socket asocket, struct sockaddr_in *addr, struct iovec *dvec,
18                    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     if (nvecs > RX_MAXIOVECS)
28         osi_Panic("osi_NetReceive: %d: too many iovecs\n", nvecs);
29
30     for (i = 0 ; i < nvecs ; i++)
31         iov[i] = dvec[i];
32
33     u.uio_iov = &iov[0];
34     u.uio_iovcnt = nvecs;
35     u.uio_offset = 0;
36     u.uio_resid = *alength;
37     u.uio_segflg = UIO_SYSSPACE;
38     u.uio_rw = UIO_READ;
39     u.uio_procp = NULL;
40
41     if (haveGlock)
42         AFS_GUNLOCK();
43     code = soreceive(asocket, (addr ? &nam : NULL), &u, NULL, NULL, NULL);
44     if (haveGlock)
45         AFS_GLOCK();
46
47     if (code) {
48 #ifdef RXKNET_DEBUG
49         printf("rx code %d termState %d\n", code, afs_termState);
50 #endif
51         while (afs_termState == AFSOP_STOP_RXEVENT)
52             afs_osi_Sleep(&afs_termState);
53         return code;
54     }
55
56     *alength -= u.uio_resid;
57     if (addr && nam) {
58         memcpy(addr, mtod(nam, caddr_t), nam->m_len);
59         m_freem(nam);
60     }
61
62     return code;
63 }
64
65 extern int rxk_ListenerPid;
66 void osi_StopListener(void)
67 {
68    struct proc *p;
69
70    soclose(rx_socket);
71    p = pfind(rxk_ListenerPid);
72    if (p)
73        psignal(p, SIGUSR1);
74 }
75
76 /*
77  * rx_NetSend - send asize bytes at adata from asocket to host at addr.
78  */
79
80 int osi_NetSend(osi_socket asocket, struct sockaddr_in *addr,
81                 struct iovec *dvec, int nvecs, afs_int32 alength, int istack)
82 {
83     int i, code;
84     struct iovec iov[RX_MAXIOVECS];
85     struct uio u;
86     struct mbuf *nam;
87     int haveGlock = ISAFS_GLOCK();
88
89     AFS_STATCNT(osi_NetSend);
90     if (nvecs > RX_MAXIOVECS)
91         osi_Panic("osi_NetSend: %d: Too many iovecs.\n", nvecs);
92
93     for (i = 0; i < nvecs; i++)
94         iov[i] = dvec[i];
95
96     u.uio_iov = &iov[0];
97     u.uio_iovcnt = nvecs;
98     u.uio_offset = 0;
99     u.uio_resid = alength;
100     u.uio_segflg = UIO_SYSSPACE;
101     u.uio_rw = UIO_WRITE;
102     u.uio_procp = NULL;
103
104     nam = m_get(M_DONTWAIT, MT_SONAME);
105     if (!nam)
106         return ENOBUFS;
107     nam->m_len = addr->sin_len = sizeof(struct sockaddr_in);
108     memcpy(mtod(nam, caddr_t), addr, addr->sin_len);
109
110     if (haveGlock)
111         AFS_GUNLOCK();
112     code = sosend(asocket, nam, &u, NULL, NULL, 0);
113     if (haveGlock)
114         AFS_GLOCK();
115     m_freem(nam);
116
117     return code;
118 }