comparison nspr/pr/src/io/prmapopt.c @ 0:1e5118fa0cb1

This is NSS with a Cmake Buildsyste To compile a static NSS library for Windows we've used the Chromium-NSS fork and added a Cmake buildsystem to compile it statically for Windows. See README.chromium for chromium changes and README.trustbridge for our modifications.
author Andre Heinecke <andre.heinecke@intevation.de>
date Mon, 28 Jul 2014 10:47:06 +0200
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:1e5118fa0cb1
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 /*
7 * This file defines _PR_MapOptionName(). The purpose of putting
8 * _PR_MapOptionName() in a separate file is to work around a Winsock
9 * header file problem on Windows NT.
10 *
11 * On Windows NT, if we define _WIN32_WINNT to be 0x0400 (in order
12 * to use Service Pack 3 extensions), windows.h includes winsock2.h
13 * (instead of winsock.h), which doesn't define many socket options
14 * defined in winsock.h.
15 *
16 * We need the socket options defined in winsock.h. So this file
17 * includes winsock.h, with _WIN32_WINNT undefined.
18 */
19
20 #if defined(WINNT) || defined(__MINGW32__)
21 #include <winsock.h>
22 #endif
23
24 /* MinGW doesn't define these in its winsock.h. */
25 #ifdef __MINGW32__
26 #ifndef IP_TTL
27 #define IP_TTL 7
28 #endif
29 #ifndef IP_TOS
30 #define IP_TOS 8
31 #endif
32 #endif
33
34 #include "primpl.h"
35
36 #ifdef HAVE_NETINET_TCP_H
37 #include <netinet/tcp.h> /* TCP_NODELAY, TCP_MAXSEG */
38 #endif
39
40 #ifndef _PR_PTHREADS
41
42 PRStatus PR_CALLBACK _PR_SocketGetSocketOption(PRFileDesc *fd, PRSocketOptionData *data)
43 {
44 PRStatus rv;
45 PRInt32 length;
46 PRInt32 level, name;
47
48 /*
49 * PR_SockOpt_Nonblocking is a special case that does not
50 * translate to a getsockopt() call
51 */
52 if (PR_SockOpt_Nonblocking == data->option)
53 {
54 data->value.non_blocking = fd->secret->nonblocking;
55 return PR_SUCCESS;
56 }
57
58 rv = _PR_MapOptionName(data->option, &level, &name);
59 if (PR_SUCCESS == rv)
60 {
61 switch (data->option)
62 {
63 case PR_SockOpt_Linger:
64 {
65 #if !defined(XP_BEOS) || defined(BONE_VERSION)
66 struct linger linger;
67 length = sizeof(linger);
68 rv = _PR_MD_GETSOCKOPT(
69 fd, level, name, (char *) &linger, &length);
70 if (PR_SUCCESS == rv)
71 {
72 PR_ASSERT(sizeof(linger) == length);
73 data->value.linger.polarity =
74 (linger.l_onoff) ? PR_TRUE : PR_FALSE;
75 data->value.linger.linger =
76 PR_SecondsToInterval(linger.l_linger);
77 }
78 break;
79 #else
80 PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 );
81 return PR_FAILURE;
82 #endif
83 }
84 case PR_SockOpt_Reuseaddr:
85 case PR_SockOpt_Keepalive:
86 case PR_SockOpt_NoDelay:
87 case PR_SockOpt_Broadcast:
88 {
89 #ifdef WIN32 /* Winsock */
90 BOOL value;
91 #else
92 PRIntn value;
93 #endif
94 length = sizeof(value);
95 rv = _PR_MD_GETSOCKOPT(
96 fd, level, name, (char*)&value, &length);
97 if (PR_SUCCESS == rv)
98 data->value.reuse_addr = (0 == value) ? PR_FALSE : PR_TRUE;
99 break;
100 }
101 case PR_SockOpt_McastLoopback:
102 {
103 #ifdef WIN32 /* Winsock */
104 BOOL bool;
105 #else
106 PRUint8 bool;
107 #endif
108 length = sizeof(bool);
109 rv = _PR_MD_GETSOCKOPT(
110 fd, level, name, (char*)&bool, &length);
111 if (PR_SUCCESS == rv)
112 data->value.mcast_loopback = (0 == bool) ? PR_FALSE : PR_TRUE;
113 break;
114 }
115 case PR_SockOpt_RecvBufferSize:
116 case PR_SockOpt_SendBufferSize:
117 case PR_SockOpt_MaxSegment:
118 {
119 PRIntn value;
120 length = sizeof(value);
121 rv = _PR_MD_GETSOCKOPT(
122 fd, level, name, (char*)&value, &length);
123 if (PR_SUCCESS == rv)
124 data->value.recv_buffer_size = value;
125 break;
126 }
127 case PR_SockOpt_IpTimeToLive:
128 case PR_SockOpt_IpTypeOfService:
129 {
130 /* These options should really be an int (or PRIntn). */
131 length = sizeof(PRUintn);
132 rv = _PR_MD_GETSOCKOPT(
133 fd, level, name, (char*)&data->value.ip_ttl, &length);
134 break;
135 }
136 case PR_SockOpt_McastTimeToLive:
137 {
138 #ifdef WIN32 /* Winsock */
139 int ttl;
140 #else
141 PRUint8 ttl;
142 #endif
143 length = sizeof(ttl);
144 rv = _PR_MD_GETSOCKOPT(
145 fd, level, name, (char*)&ttl, &length);
146 if (PR_SUCCESS == rv)
147 data->value.mcast_ttl = ttl;
148 break;
149 }
150 #ifdef IP_ADD_MEMBERSHIP
151 case PR_SockOpt_AddMember:
152 case PR_SockOpt_DropMember:
153 {
154 struct ip_mreq mreq;
155 length = sizeof(mreq);
156 rv = _PR_MD_GETSOCKOPT(
157 fd, level, name, (char*)&mreq, &length);
158 if (PR_SUCCESS == rv)
159 {
160 data->value.add_member.mcaddr.inet.ip =
161 mreq.imr_multiaddr.s_addr;
162 data->value.add_member.ifaddr.inet.ip =
163 mreq.imr_interface.s_addr;
164 }
165 break;
166 }
167 #endif /* IP_ADD_MEMBERSHIP */
168 case PR_SockOpt_McastInterface:
169 {
170 /* This option is a struct in_addr. */
171 length = sizeof(data->value.mcast_if.inet.ip);
172 rv = _PR_MD_GETSOCKOPT(
173 fd, level, name,
174 (char*)&data->value.mcast_if.inet.ip, &length);
175 break;
176 }
177 default:
178 PR_NOT_REACHED("Unknown socket option");
179 break;
180 }
181 }
182 return rv;
183 } /* _PR_SocketGetSocketOption */
184
185 PRStatus PR_CALLBACK _PR_SocketSetSocketOption(PRFileDesc *fd, const PRSocketOptionData *data)
186 {
187 PRStatus rv;
188 PRInt32 level, name;
189
190 /*
191 * PR_SockOpt_Nonblocking is a special case that does not
192 * translate to a setsockopt call.
193 */
194 if (PR_SockOpt_Nonblocking == data->option)
195 {
196 #ifdef WINNT
197 PR_ASSERT((fd->secret->md.io_model_committed == PR_FALSE)
198 || (fd->secret->nonblocking == data->value.non_blocking));
199 if (fd->secret->md.io_model_committed
200 && (fd->secret->nonblocking != data->value.non_blocking))
201 {
202 /*
203 * On NT, once we have associated a socket with the io
204 * completion port, we can't disassociate it. So we
205 * can't change the nonblocking option of the socket
206 * afterwards.
207 */
208 PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
209 return PR_FAILURE;
210 }
211 #endif
212 fd->secret->nonblocking = data->value.non_blocking;
213 return PR_SUCCESS;
214 }
215
216 rv = _PR_MapOptionName(data->option, &level, &name);
217 if (PR_SUCCESS == rv)
218 {
219 switch (data->option)
220 {
221 case PR_SockOpt_Linger:
222 {
223 #if !defined(XP_BEOS) || defined(BONE_VERSION)
224 struct linger linger;
225 linger.l_onoff = data->value.linger.polarity;
226 linger.l_linger = PR_IntervalToSeconds(data->value.linger.linger);
227 rv = _PR_MD_SETSOCKOPT(
228 fd, level, name, (char*)&linger, sizeof(linger));
229 break;
230 #else
231 PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 );
232 return PR_FAILURE;
233 #endif
234 }
235 case PR_SockOpt_Reuseaddr:
236 case PR_SockOpt_Keepalive:
237 case PR_SockOpt_NoDelay:
238 case PR_SockOpt_Broadcast:
239 {
240 #ifdef WIN32 /* Winsock */
241 BOOL value;
242 #else
243 PRIntn value;
244 #endif
245 value = (data->value.reuse_addr) ? 1 : 0;
246 rv = _PR_MD_SETSOCKOPT(
247 fd, level, name, (char*)&value, sizeof(value));
248 break;
249 }
250 case PR_SockOpt_McastLoopback:
251 {
252 #ifdef WIN32 /* Winsock */
253 BOOL bool;
254 #else
255 PRUint8 bool;
256 #endif
257 bool = data->value.mcast_loopback ? 1 : 0;
258 rv = _PR_MD_SETSOCKOPT(
259 fd, level, name, (char*)&bool, sizeof(bool));
260 break;
261 }
262 case PR_SockOpt_RecvBufferSize:
263 case PR_SockOpt_SendBufferSize:
264 case PR_SockOpt_MaxSegment:
265 {
266 PRIntn value = data->value.recv_buffer_size;
267 rv = _PR_MD_SETSOCKOPT(
268 fd, level, name, (char*)&value, sizeof(value));
269 break;
270 }
271 case PR_SockOpt_IpTimeToLive:
272 case PR_SockOpt_IpTypeOfService:
273 {
274 /* These options should really be an int (or PRIntn). */
275 rv = _PR_MD_SETSOCKOPT(
276 fd, level, name, (char*)&data->value.ip_ttl, sizeof(PRUintn));
277 break;
278 }
279 case PR_SockOpt_McastTimeToLive:
280 {
281 #ifdef WIN32 /* Winsock */
282 int ttl;
283 #else
284 PRUint8 ttl;
285 #endif
286 ttl = data->value.mcast_ttl;
287 rv = _PR_MD_SETSOCKOPT(
288 fd, level, name, (char*)&ttl, sizeof(ttl));
289 break;
290 }
291 #ifdef IP_ADD_MEMBERSHIP
292 case PR_SockOpt_AddMember:
293 case PR_SockOpt_DropMember:
294 {
295 struct ip_mreq mreq;
296 mreq.imr_multiaddr.s_addr =
297 data->value.add_member.mcaddr.inet.ip;
298 mreq.imr_interface.s_addr =
299 data->value.add_member.ifaddr.inet.ip;
300 rv = _PR_MD_SETSOCKOPT(
301 fd, level, name, (char*)&mreq, sizeof(mreq));
302 break;
303 }
304 #endif /* IP_ADD_MEMBERSHIP */
305 case PR_SockOpt_McastInterface:
306 {
307 /* This option is a struct in_addr. */
308 rv = _PR_MD_SETSOCKOPT(
309 fd, level, name, (char*)&data->value.mcast_if.inet.ip,
310 sizeof(data->value.mcast_if.inet.ip));
311 break;
312 }
313 default:
314 PR_NOT_REACHED("Unknown socket option");
315 break;
316 }
317 }
318 return rv;
319 } /* _PR_SocketSetSocketOption */
320
321 #endif /* ! _PR_PTHREADS */
322
323 /*
324 *********************************************************************
325 *********************************************************************
326 **
327 ** Make sure that the following is at the end of this file,
328 ** because we will be playing with macro redefines.
329 **
330 *********************************************************************
331 *********************************************************************
332 */
333
334 /*
335 * Not every platform has all the socket options we want to
336 * support. Some older operating systems such as SunOS 4.1.3
337 * don't have the IP multicast socket options. Win32 doesn't
338 * have TCP_MAXSEG.
339 *
340 * To deal with this problem, we define the missing socket
341 * options as _PR_NO_SUCH_SOCKOPT. _PR_MapOptionName() fails with
342 * PR_OPERATION_NOT_SUPPORTED_ERROR if a socket option not
343 * available on the platform is requested.
344 */
345
346 /*
347 * Sanity check. SO_LINGER and TCP_NODELAY should be available
348 * on all platforms. Just to make sure we have included the
349 * appropriate header files. Then any undefined socket options
350 * are really missing.
351 */
352
353 #if !defined(SO_LINGER)
354 #error "SO_LINGER is not defined"
355 #endif
356
357 #if !defined(TCP_NODELAY)
358 #error "TCP_NODELAY is not defined"
359 #endif
360
361 /*
362 * Make sure the value of _PR_NO_SUCH_SOCKOPT is not
363 * a valid socket option.
364 */
365 #define _PR_NO_SUCH_SOCKOPT -1
366
367 #ifndef SO_KEEPALIVE
368 #define SO_KEEPALIVE _PR_NO_SUCH_SOCKOPT
369 #endif
370
371 #ifndef SO_SNDBUF
372 #define SO_SNDBUF _PR_NO_SUCH_SOCKOPT
373 #endif
374
375 #ifndef SO_RCVBUF
376 #define SO_RCVBUF _PR_NO_SUCH_SOCKOPT
377 #endif
378
379 #ifndef IP_MULTICAST_IF /* set/get IP multicast interface */
380 #define IP_MULTICAST_IF _PR_NO_SUCH_SOCKOPT
381 #endif
382
383 #ifndef IP_MULTICAST_TTL /* set/get IP multicast timetolive */
384 #define IP_MULTICAST_TTL _PR_NO_SUCH_SOCKOPT
385 #endif
386
387 #ifndef IP_MULTICAST_LOOP /* set/get IP multicast loopback */
388 #define IP_MULTICAST_LOOP _PR_NO_SUCH_SOCKOPT
389 #endif
390
391 #ifndef IP_ADD_MEMBERSHIP /* add an IP group membership */
392 #define IP_ADD_MEMBERSHIP _PR_NO_SUCH_SOCKOPT
393 #endif
394
395 #ifndef IP_DROP_MEMBERSHIP /* drop an IP group membership */
396 #define IP_DROP_MEMBERSHIP _PR_NO_SUCH_SOCKOPT
397 #endif
398
399 #ifndef IP_TTL /* set/get IP Time To Live */
400 #define IP_TTL _PR_NO_SUCH_SOCKOPT
401 #endif
402
403 #ifndef IP_TOS /* set/get IP Type Of Service */
404 #define IP_TOS _PR_NO_SUCH_SOCKOPT
405 #endif
406
407 #ifndef TCP_NODELAY /* don't delay to coalesce data */
408 #define TCP_NODELAY _PR_NO_SUCH_SOCKOPT
409 #endif
410
411 #ifndef TCP_MAXSEG /* maxumum segment size for tcp */
412 #define TCP_MAXSEG _PR_NO_SUCH_SOCKOPT
413 #endif
414
415 #ifndef SO_BROADCAST /* enable broadcast on udp sockets */
416 #define SO_BROADCAST _PR_NO_SUCH_SOCKOPT
417 #endif
418
419 PRStatus _PR_MapOptionName(
420 PRSockOption optname, PRInt32 *level, PRInt32 *name)
421 {
422 static PRInt32 socketOptions[PR_SockOpt_Last] =
423 {
424 0, SO_LINGER, SO_REUSEADDR, SO_KEEPALIVE, SO_RCVBUF, SO_SNDBUF,
425 IP_TTL, IP_TOS, IP_ADD_MEMBERSHIP, IP_DROP_MEMBERSHIP,
426 IP_MULTICAST_IF, IP_MULTICAST_TTL, IP_MULTICAST_LOOP,
427 TCP_NODELAY, TCP_MAXSEG, SO_BROADCAST
428 };
429 static PRInt32 socketLevels[PR_SockOpt_Last] =
430 {
431 0, SOL_SOCKET, SOL_SOCKET, SOL_SOCKET, SOL_SOCKET, SOL_SOCKET,
432 IPPROTO_IP, IPPROTO_IP, IPPROTO_IP, IPPROTO_IP,
433 IPPROTO_IP, IPPROTO_IP, IPPROTO_IP,
434 IPPROTO_TCP, IPPROTO_TCP, SOL_SOCKET
435 };
436
437 if ((optname < PR_SockOpt_Linger)
438 || (optname >= PR_SockOpt_Last))
439 {
440 PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
441 return PR_FAILURE;
442 }
443
444 if (socketOptions[optname] == _PR_NO_SUCH_SOCKOPT)
445 {
446 PR_SetError(PR_OPERATION_NOT_SUPPORTED_ERROR, 0);
447 return PR_FAILURE;
448 }
449 *name = socketOptions[optname];
450 *level = socketLevels[optname];
451 return PR_SUCCESS;
452 } /* _PR_MapOptionName */
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)