Mercurial > trustbridge > nss-cmake-static
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 */ |