a6e8e0ccf330c269e975a32f3917fb53772de985
[openafs.git] / src / rx / xdr_rx.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 /*
11  * xdr_rx.c.  XDR using RX.
12  */
13
14 #include <afsconfig.h>
15 #include <afs/param.h>
16
17 #ifdef KERNEL
18 # include "afs/sysincludes.h"
19 # ifndef UKERNEL
20 #  include "h/types.h"
21 #  include "h/uio.h"
22 #  ifdef AFS_LINUX20_ENV
23 #   include "h/socket.h"
24 #  else
25 #   include "rpc/types.h"
26 #  endif
27 #  ifdef AFS_LINUX22_ENV
28 #   ifndef quad_t
29 #    define quad_t __quad_t
30 #    define u_quad_t __u_quad_t
31 #   endif
32 #  endif
33 #  include "netinet/in.h"
34 # endif /* !UKERNEL */
35 #else /* KERNEL */
36 # include <roken.h>
37 #endif /* KERNEL */
38
39 #include "rx.h"
40 #include "xdr.h"
41
42 /* Static prototypes */
43 #ifdef AFS_XDR_64BITOPS
44 static bool_t xdrrx_getint64(XDR *axdrs, long *lp);
45 static bool_t xdrrx_putint64(XDR *axdrs, long *lp);
46 #endif /* AFS_XDR_64BITOPS */
47
48 static bool_t xdrrx_getint32(XDR *axdrs, afs_int32 * lp);
49 static bool_t xdrrx_putint32(XDR *axdrs, afs_int32 * lp);
50 static bool_t xdrrx_getbytes(XDR *axdrs, caddr_t addr,
51                              u_int len);
52 static bool_t xdrrx_putbytes(XDR *axdrs, caddr_t addr,
53                              u_int len);
54 static afs_int32 *xdrrx_inline(XDR *axdrs, u_int len);
55
56
57 /*
58  * Ops vector for stdio type XDR
59  */
60 static struct xdr_ops xdrrx_ops = {
61 #ifndef HAVE_STRUCT_LABEL_SUPPORT
62 #ifdef AFS_XDR_64BITOPS
63     xdrrx_getint64,     /* deserialize an afs_int64 */
64     xdrrx_putint64,     /* serialize an afs_int64 */
65 #endif
66     /* Windows does not support labeled assigments */
67 #if !(defined(KERNEL) && defined(AFS_SUN57_ENV))
68     xdrrx_getint32,     /* deserialize an afs_int32 */
69     xdrrx_putint32,     /* serialize an afs_int32 */
70 #endif
71     xdrrx_getbytes,     /* deserialize counted bytes */
72     xdrrx_putbytes,     /* serialize counted bytes */
73     NULL,               /* get offset in the stream: not supported. */
74     NULL,               /* set offset in the stream: not supported. */
75     xdrrx_inline,       /* prime stream for inline macros */
76     NULL,               /* destroy stream */
77 #if (defined(KERNEL) && defined(AFS_SUN57_ENV))
78     NULL,               /* control - not implemented */
79     xdrrx_getint32,     /* not supported */
80     xdrrx_putint32,     /* serialize an afs_int32 */
81 #endif
82 #else
83 #ifdef AFS_XDR_64BITOPS
84     .x_getint64 = xdrrx_getint64,
85     .x_putint64 = xdrrx_putint64,
86 #endif /* AFS_XDR_64BITOPS */
87     .x_getint32 = xdrrx_getint32,       /* deserialize an afs_int32 */
88     .x_putint32 = xdrrx_putint32,       /* serialize an afs_int32 */
89     .x_getbytes = xdrrx_getbytes,       /* deserialize counted bytes */
90     .x_putbytes = xdrrx_putbytes,       /* serialize counted bytes */
91     .x_getpostn = NULL,         /* get offset in the stream: not supported. */
92     .x_setpostn = NULL,         /* set offset in the stream: not supported. */
93     .x_inline = xdrrx_inline,           /* prime stream for inline macros */
94     .x_destroy = NULL,                  /* destroy stream */
95 #if defined(KERNEL) && defined(AFS_SUN57_ENV)
96     .x_control = NULL,
97 #endif
98 #endif
99 };
100
101 /*
102  * Initialize an rx xdr handle, for a given rx call.  op must be XDR_ENCODE or XDR_DECODE.
103  * Call must have been returned by rx_MakeCall or rx_GetCall.
104  */
105 void
106 xdrrx_create(XDR * xdrs, struct rx_call *call,
107              enum xdr_op op)
108 {
109     xdrs->x_op = op;
110     xdrs->x_ops = &xdrrx_ops;
111     xdrs->x_private = (caddr_t) call;
112 }
113
114 #if     defined(KERNEL) && defined(AFS_AIX32_ENV)
115 #define STACK_TO_PIN    2*PAGESIZE      /* 8K */
116 int rx_pin_failed = 0;
117 #endif
118
119 #ifdef AFS_XDR_64BITOPS
120 static bool_t
121 xdrrx_getint64(XDR *axdrs, long *lp)
122 {
123     XDR * xdrs = (XDR *)axdrs;
124     struct rx_call *call = ((struct rx_call *)(xdrs)->x_private);
125     afs_int32 i;
126
127     if (rx_Read32(call, &i) == sizeof(i)) {
128         *lp = ntohl(i);
129         return TRUE;
130     }
131     return FALSE;
132 }
133
134 static bool_t
135 xdrrx_putint64(XDR *axdrs, long *lp)
136 {
137     XDR * xdrs = (XDR *)axdrs;
138     afs_int32 code, i = htonl(*lp);
139     struct rx_call *call = ((struct rx_call *)(xdrs)->x_private);
140
141     code = (rx_Write32(call, &i) == sizeof(i));
142     return code;
143 }
144 #endif /* AFS_XDR_64BITOPS */
145
146 static bool_t
147 xdrrx_getint32(XDR *axdrs, afs_int32 * lp)
148 {
149     afs_int32 l;
150     XDR * xdrs = (XDR *)axdrs;
151     struct rx_call *call = ((struct rx_call *)(xdrs)->x_private);
152 #if     defined(KERNEL) && defined(AFS_AIX32_ENV)
153     char *saddr = (char *)&l;
154     saddr -= STACK_TO_PIN;
155     /*
156      * Hack of hacks: Aix3.2 only guarantees that the next 2K of stack in pinned. Under
157      * splnet (disables interrupts), which is set throughout rx, we can't swap in stack
158      * pages if we need so we panic. Since sometimes, under splnet, we'll use more than
159      * 2K stack we could try to bring the next few stack pages in here before we call the rx
160      * layer. Of course this doesn't guarantee that those stack pages won't be swapped
161      * out between here and calling splnet. So we now pin (and unpin) them instead to
162      * guarantee that they remain there.
163      */
164     if (pin(saddr, STACK_TO_PIN)) {
165         /* XXX There's little we can do by continue XXX */
166         saddr = NULL;
167         rx_pin_failed++;
168     }
169 #endif
170     if (rx_Read32(call, &l) == sizeof(l)) {
171         *lp = ntohl(l);
172 #if     defined(KERNEL) && defined(AFS_AIX32_ENV)
173         if (saddr)
174             unpin(saddr, STACK_TO_PIN);
175 #endif
176         return TRUE;
177     }
178 #if     defined(KERNEL) && defined(AFS_AIX32_ENV)
179     if (saddr)
180         unpin(saddr, STACK_TO_PIN);
181 #endif
182     return FALSE;
183 }
184
185 static bool_t
186 xdrrx_putint32(XDR *axdrs, afs_int32 * lp)
187 {
188     afs_int32 code, l = htonl(*lp);
189     XDR * xdrs = (XDR *)axdrs;
190     struct rx_call *call = ((struct rx_call *)(xdrs)->x_private);
191 #if     defined(KERNEL) && defined(AFS_AIX32_ENV)
192     char *saddr = (char *)&code;
193     saddr -= STACK_TO_PIN;
194     /*
195      * Hack of hacks: Aix3.2 only guarantees that the next 2K of stack in pinned. Under
196      * splnet (disables interrupts), which is set throughout rx, we can't swap in stack
197      * pages if we need so we panic. Since sometimes, under splnet, we'll use more than
198      * 2K stack we could try to bring the next few stack pages in here before we call the rx
199      * layer. Of course this doesn't guarantee that those stack pages won't be swapped
200      * out between here and calling splnet. So we now pin (and unpin) them instead to
201      * guarantee that they remain there.
202      */
203     if (pin(saddr, STACK_TO_PIN)) {
204         saddr = NULL;
205         rx_pin_failed++;
206     }
207 #endif
208     code = (rx_Write32(call, &l) == sizeof(l));
209 #if     defined(KERNEL) && defined(AFS_AIX32_ENV)
210     if (saddr)
211         unpin(saddr, STACK_TO_PIN);
212 #endif
213     return code;
214 }
215
216 static bool_t
217 xdrrx_getbytes(XDR *axdrs, caddr_t addr, u_int len)
218 {
219     afs_int32 code;
220     XDR * xdrs = (XDR *)axdrs;
221     struct rx_call *call = ((struct rx_call *)(xdrs)->x_private);
222 #if     defined(KERNEL) && defined(AFS_AIX32_ENV)
223     char *saddr = (char *)&code;
224     saddr -= STACK_TO_PIN;
225     /*
226      * Hack of hacks: Aix3.2 only guarantees that the next 2K of stack in pinned. Under
227      * splnet (disables interrupts), which is set throughout rx, we can't swap in stack
228      * pages if we need so we panic. Since sometimes, under splnet, we'll use more than
229      * 2K stack we could try to bring the next few stack pages in here before we call the rx
230      * layer. Of course this doesn't guarantee that those stack pages won't be swapped
231      * out between here and calling splnet. So we now pin (and unpin) them instead to
232      * guarantee that they remain there.
233      */
234     if (pin(saddr, STACK_TO_PIN)) {
235         /* XXX There's little we can do by continue XXX */
236         saddr = NULL;
237         rx_pin_failed++;
238     }
239 #endif
240     code = (rx_Read(call, addr, len) == len);
241 #if     defined(KERNEL) && defined(AFS_AIX32_ENV)
242     if (saddr)
243         unpin(saddr, STACK_TO_PIN);
244 #endif
245     return code;
246 }
247
248 static bool_t
249 xdrrx_putbytes(XDR *axdrs, caddr_t addr, u_int len)
250 {
251     afs_int32 code;
252     XDR * xdrs = (XDR *)axdrs;
253     struct rx_call *call = ((struct rx_call *)(xdrs)->x_private);
254 #if     defined(KERNEL) && defined(AFS_AIX32_ENV)
255     char *saddr = (char *)&code;
256     saddr -= STACK_TO_PIN;
257     /*
258      * Hack of hacks: Aix3.2 only guarantees that the next 2K of stack in pinned. Under
259      * splnet (disables interrupts), which is set throughout rx, we can't swap in stack
260      * pages if we need so we panic. Since sometimes, under splnet, we'll use more than
261      * 2K stack we could try to bring the next few stack pages in here before we call the rx
262      * layer. Of course this doesn't guarantee that those stack pages won't be swapped
263      * out between here and calling splnet. So we now pin (and unpin) them instead to
264      * guarantee that they remain there.
265      */
266     if (pin(saddr, STACK_TO_PIN)) {
267         /* XXX There's little we can do by continue XXX */
268         saddr = NULL;
269         rx_pin_failed++;
270     }
271 #endif
272     code = (rx_Write(call, addr, len) == len);
273 #if     defined(KERNEL) && defined(AFS_AIX32_ENV)
274     if (saddr)
275         unpin(saddr, STACK_TO_PIN);
276 #endif
277     return code;
278 }
279
280 #ifdef undef                    /* not used */
281 static u_int
282 xdrrx_getpos(XDR * xdrs)
283 {
284     /* Not supported.  What error code should we return? (It doesn't matter:  it will never be called, anyway!) */
285     return -1;
286 }
287
288 static bool_t
289 xdrrx_setpos(XDR * xdrs, u_int pos)
290 {
291     /* Not supported */
292     return FALSE;
293 }
294 #endif
295
296 static afs_int32 *
297 xdrrx_inline(XDR *axdrs, u_int len)
298 {
299     /* I don't know what this routine is supposed to do, but the stdio module returns null, so we will, too */
300     return (0);
301 }