File: | s/lib/libpkix/pkix_pl_nss/module/pkix_pl_socket.c |
Warning: | line 1156, column 37 Dereference of null pointer (loaded from variable 'pBytesRead') |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* This Source Code Form is subject to the terms of the Mozilla Public | |||
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this | |||
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |||
4 | /* | |||
5 | * pkix_pl_socket.c | |||
6 | * | |||
7 | * Socket Function Definitions | |||
8 | * | |||
9 | */ | |||
10 | ||||
11 | /* | |||
12 | * If Socket Tracing is active, messages sent and received will be | |||
13 | * timestamped and dumped (to stdout) in standard hex-dump format. E.g., | |||
14 | * | |||
15 | * 1116612359156140: | |||
16 | * 28F0: 48 65 6C 6C 6F 2C 20 77 6F 72 6C 64 21 00 Hello, world!. | |||
17 | * | |||
18 | * The timestamp is not formatted to be meaningful except as an increasing | |||
19 | * value of seconds.microseconds, which is good enough to correlate two | |||
20 | * sides of a message exchange and to figure durations. | |||
21 | * | |||
22 | * Code to perform Socket tracing will be compiled in if PKIX_SOCKETTRACE | |||
23 | * is defined, but that doesn't mean socket tracing is active. Tracing also | |||
24 | * requires that the Boolean socketTraceFlag is set to PKIX_TRUE. That is | |||
25 | * the default value, but it can be overridden by using the debugger to | |||
26 | * change its value -- allowing tracing to be turned on and off at various | |||
27 | * breakpoints -- or by setting the environment variable SOCKETTRACE. A | |||
28 | * value of 1 sets socketTraceFlag to PKIX_TRUE (tracing on), and any other | |||
29 | * value sets socketTraceFlag to PKIX_FALSE (tracing off). The environment | |||
30 | * value is checked during system initialization. | |||
31 | */ | |||
32 | #ifndef BUILD_OPT | |||
33 | #define PKIX_SOCKETTRACE1 1 | |||
34 | #endif | |||
35 | ||||
36 | #ifdef PKIX_SOCKETDEBUG | |||
37 | #define PKIX_SOCKETTRACE1 1 | |||
38 | #endif | |||
39 | ||||
40 | #include "pkix_pl_socket.h" | |||
41 | ||||
42 | /* --Private-Socket-Functions---------------------------------- */ | |||
43 | ||||
44 | #ifdef PKIX_SOCKETTRACE1 | |||
45 | static PKIX_Boolean socketTraceFlag = PKIX_FALSE((PKIX_Boolean) 0); | |||
46 | ||||
47 | /* | |||
48 | * FUNCTION: pkix_pl_socket_timestamp | |||
49 | * DESCRIPTION: | |||
50 | * | |||
51 | * This functions prints to stdout the time of day, as obtained from the | |||
52 | * system function gettimeofday, as seconds.microseconds. Its resolution | |||
53 | * is whatever the system call provides. | |||
54 | * | |||
55 | * PARAMETERS: | |||
56 | * none | |||
57 | * THREAD SAFETY: | |||
58 | * Thread Safe (see Thread Safety definitions in Programmer's Guide) | |||
59 | * RETURNS: | |||
60 | * none | |||
61 | */ | |||
62 | static void pkix_pl_socket_timestamp() { | |||
63 | PRInt64 prTime; | |||
64 | prTime = PR_Now(); | |||
65 | /* We shouldn't use PR_ALTERNATE_INT64_TYPEDEF, but nor can we use PRId64 */ | |||
66 | #if PR_BYTES_PER_LONG8 == 8 && !defined(PR_ALTERNATE_INT64_TYPEDEF) | |||
67 | printf("%ld:\n", prTime); | |||
68 | #else | |||
69 | printf("%lld:\n", prTime); | |||
70 | #endif | |||
71 | } | |||
72 | ||||
73 | /* | |||
74 | * FUNCTION: pkix_pl_socket_hexDigit | |||
75 | * DESCRIPTION: | |||
76 | * | |||
77 | * This functions prints to stdout the byte "byteVal" as two hex digits. | |||
78 | * | |||
79 | * PARAMETERS: | |||
80 | * "byteVal" | |||
81 | * The value to be printed. | |||
82 | * THREAD SAFETY: | |||
83 | * Thread Safe (see Thread Safety definitions in Programmer's Guide) | |||
84 | * RETURNS: | |||
85 | * none | |||
86 | */ | |||
87 | static void pkix_pl_socket_hexDigit(char byteVal) { | |||
88 | int n = 0; | |||
89 | char cHi = '\0'; | |||
90 | char cLow = '\0'; | |||
91 | n = ((byteVal >> 4) & 0xf); | |||
92 | if (n > 9) { | |||
93 | cHi = (char) ((n - 10) + 'A'); | |||
94 | } else { | |||
95 | cHi = (char) (n + '0'); | |||
96 | } | |||
97 | n = byteVal & 0xf; | |||
98 | if (n > 9) { | |||
99 | cLow = (char) ((n - 10) + 'A'); | |||
100 | } else { | |||
101 | cLow = (char) (n + '0'); | |||
102 | } | |||
103 | (void) printf("%c%c", cHi, cLow); | |||
104 | } | |||
105 | ||||
106 | /* | |||
107 | * FUNCTION: pkix_pl_socket_linePrefix | |||
108 | * DESCRIPTION: | |||
109 | * | |||
110 | * This functions prints to stdout the address provided by "addr" as four | |||
111 | * hexadecimal digits followed by a colon and a space. | |||
112 | * | |||
113 | * PARAMETERS: | |||
114 | * "addr" | |||
115 | * The address to be printed | |||
116 | * none | |||
117 | * THREAD SAFETY: | |||
118 | * Thread Safe (see Thread Safety definitions in Programmer's Guide) | |||
119 | * RETURNS: | |||
120 | * none | |||
121 | */ | |||
122 | static void pkix_pl_socket_linePrefix(PKIX_UInt32 addr) { | |||
123 | pkix_pl_socket_hexDigit((char)((addr >> 8) & 0xff)); | |||
124 | pkix_pl_socket_hexDigit((char)(addr & 0xff)); | |||
125 | (void) printf(": "); | |||
126 | } | |||
127 | ||||
128 | /* | |||
129 | * FUNCTION: pkix_pl_socket_traceLine | |||
130 | * DESCRIPTION: | |||
131 | * | |||
132 | * This functions prints to stdout the sixteen bytes beginning at the | |||
133 | * address pointed to by "ptr". The bytes are printed as sixteen pairs | |||
134 | * of hexadecimal characters followed by an ascii interpretation, in which | |||
135 | * characters from 0x20 to 0x7d are shown as their ascii equivalents, and | |||
136 | * other values are represented as periods. | |||
137 | * | |||
138 | * PARAMETERS: | |||
139 | * "ptr" | |||
140 | * The address of the first of the bytes to be printed | |||
141 | * THREAD SAFETY: | |||
142 | * Thread Safe (see Thread Safety definitions in Programmer's Guide) | |||
143 | * RETURNS: | |||
144 | * none | |||
145 | */ | |||
146 | static void pkix_pl_socket_traceLine(char *ptr) { | |||
147 | PKIX_UInt32 i = 0; | |||
148 | pkix_pl_socket_linePrefix((PKIX_UInt32)((char *)ptr - (char *)NULL((void*)0))); | |||
149 | for (i = 0; i < 16; i++) { | |||
150 | printf(" "); | |||
151 | pkix_pl_socket_hexDigit(ptr[i]); | |||
152 | if (i == 7) { | |||
153 | printf(" "); | |||
154 | } | |||
155 | } | |||
156 | printf(" "); | |||
157 | for (i = 0; i < 16; i++) { | |||
158 | if ((ptr[i] < ' ') || (ptr[i] > '}')) { | |||
159 | printf("."); | |||
160 | } else { | |||
161 | printf("%c", ptr[i]); | |||
162 | } | |||
163 | } | |||
164 | printf("\n"); | |||
165 | } | |||
166 | ||||
167 | /* | |||
168 | * FUNCTION: pkix_pl_socket_tracePartialLine | |||
169 | * DESCRIPTION: | |||
170 | * | |||
171 | * This functions prints to stdout the number of bytes given by "nBytes", | |||
172 | * beginning at the address pointed to by "ptr". The bytes are printed as | |||
173 | * pairs of hexadecimal characters followed by an ascii interpretation, in | |||
174 | * which characters from 0x20 to 0x7d are shown as their ascii equivalents, | |||
175 | * and other values are represented as periods. | |||
176 | * | |||
177 | * PARAMETERS: | |||
178 | * "ptr" | |||
179 | * The address of the first of the bytes to be printed | |||
180 | * "nBytes" | |||
181 | * The Int32 value giving the number of bytes to be printed. If "nBytes" | |||
182 | * is greater than sixteen, the results will be unattractive. | |||
183 | * none | |||
184 | * THREAD SAFETY: | |||
185 | * Thread Safe (see Thread Safety definitions in Programmer's Guide) | |||
186 | * RETURNS: | |||
187 | * none | |||
188 | */ | |||
189 | static void pkix_pl_socket_tracePartialLine(char *ptr, PKIX_UInt32 nBytes) { | |||
190 | PKIX_UInt32 i = 0; | |||
191 | if (nBytes > 0) { | |||
192 | pkix_pl_socket_linePrefix((PKIX_UInt32)((char *)ptr - (char *)NULL((void*)0))); | |||
193 | } | |||
194 | for (i = 0; i < nBytes; i++) { | |||
195 | printf(" "); | |||
196 | pkix_pl_socket_hexDigit(ptr[i]); | |||
197 | if (i == 7) { | |||
198 | printf(" "); | |||
199 | } | |||
200 | } | |||
201 | for (i = nBytes; i < 16; i++) { | |||
202 | printf(" "); | |||
203 | if (i == 7) { | |||
204 | printf(" "); | |||
205 | } | |||
206 | } | |||
207 | printf(" "); | |||
208 | for (i = 0; i < nBytes; i++) { | |||
209 | if ((ptr[i] < ' ') || (ptr[i] > '}')) { | |||
210 | printf("."); | |||
211 | } else { | |||
212 | printf("%c", ptr[i]); | |||
213 | } | |||
214 | } | |||
215 | printf("\n"); | |||
216 | } | |||
217 | ||||
218 | /* | |||
219 | * FUNCTION: pkix_pl_socket_tracebuff | |||
220 | * DESCRIPTION: | |||
221 | * | |||
222 | * This functions prints to stdout the number of bytes given by "nBytes", | |||
223 | * beginning with the byte pointed to by "buf". The output is preceded by | |||
224 | * a timestamp, and each group of sixteen (and a remainder, if any) is | |||
225 | * preceded by its address. The contents are shown in hexadecimal and as | |||
226 | * ascii characters. If "nBytes" is zero, the timestamp and starting | |||
227 | * address are displayed. | |||
228 | * | |||
229 | * PARAMETERS: | |||
230 | * "buf" | |||
231 | * The starting address of the bytes to be printed | |||
232 | * "nBytes" | |||
233 | * The number of bytes to be printed | |||
234 | * THREAD SAFETY: | |||
235 | * Thread Safe (see Thread Safety definitions in Programmer's Guide) | |||
236 | * RETURNS: | |||
237 | * none | |||
238 | */ | |||
239 | void pkix_pl_socket_tracebuff(void *buf, PKIX_UInt32 nBytes) { | |||
240 | PKIX_UInt32 bytesRemaining = nBytes; | |||
241 | PKIX_UInt32 offset = 0; | |||
242 | char *bufptr = (char *)buf; | |||
243 | ||||
244 | if (socketTraceFlag == PKIX_FALSE((PKIX_Boolean) 0)) return; | |||
245 | ||||
246 | pkix_pl_socket_timestamp(); | |||
247 | /* | |||
248 | * Special case: if called with length of zero, just do address | |||
249 | */ | |||
250 | if (nBytes == 0) { | |||
251 | pkix_pl_socket_linePrefix((PKIX_UInt32)((char *)buf - (char *)NULL((void*)0))); | |||
252 | printf("\n"); | |||
253 | } else { | |||
254 | while (bytesRemaining >= 16) { | |||
255 | pkix_pl_socket_traceLine(&bufptr[offset]); | |||
256 | bytesRemaining -= 16; | |||
257 | offset += 16; | |||
258 | } | |||
259 | pkix_pl_socket_tracePartialLine | |||
260 | (&bufptr[offset], bytesRemaining); | |||
261 | } | |||
262 | } | |||
263 | ||||
264 | #endif | |||
265 | ||||
266 | /* | |||
267 | * FUNCTION: pkix_pl_Socket_SetNonBlocking | |||
268 | * DESCRIPTION: | |||
269 | * | |||
270 | * This functions sets the socket represented by the PRFileDesc "fileDesc" | |||
271 | * to nonblocking mode. | |||
272 | * | |||
273 | * PARAMETERS: | |||
274 | * "fileDesc" | |||
275 | * The address of the PRFileDesc whose I/O mode is to be set | |||
276 | * non-blocking. Must be non-NULL. | |||
277 | * "plContext" | |||
278 | * Platform-specific context pointer | |||
279 | * THREAD SAFETY: | |||
280 | * Thread Safe (see Thread Safety definitions in Programmer's Guide) | |||
281 | * RETURNS: | |||
282 | * none | |||
283 | */ | |||
284 | static PKIX_Error * | |||
285 | pkix_pl_Socket_SetNonBlocking( | |||
286 | PRFileDesc *fileDesc, | |||
287 | void *plContext) | |||
288 | { | |||
289 | PRStatus rv = PR_FAILURE; | |||
290 | PRSocketOptionData sockOptionData; | |||
291 | ||||
292 | PKIX_ENTER(SOCKET, "pkix_pl_Socket_SetNonBlocking")static const char cMyFuncName[] = {"pkix_pl_Socket_SetNonBlocking" }; PKIX_StdVars stdVars = zeroStdVars; stdVars.aMyFuncName = cMyFuncName ; stdVars.aPkixType = PKIX_SOCKET_ERROR; ; do { if (pkixLoggersDebugTrace ) { pkix_Logger_Check(pkixLoggersDebugTrace, stdVars.aMyFuncName , ">>>", stdVars.aPkixType, 5, plContext); } } while (0);; | |||
293 | PKIX_NULLCHECK_ONE(fileDesc)do { if ((fileDesc) == ((void*)0)){ stdVars.aPkixErrorReceived = ((PKIX_Boolean) 1); stdVars.aPkixErrorCode = PKIX_NULLARGUMENT ; return PKIX_DoReturn(&stdVars, (PKIX_FATAL_ERROR), ((PKIX_Boolean ) 1), plContext);; } } while (0); | |||
294 | ||||
295 | sockOptionData.option = PR_SockOpt_Nonblocking; | |||
296 | sockOptionData.value.non_blocking = PR_TRUE1; | |||
297 | ||||
298 | PKIX_PL_NSSCALLRV(SOCKET, rv, fileDesc->methods->setsocketoption,; rv = (fileDesc->methods->setsocketoption (fileDesc, & sockOptionData)) | |||
299 | (fileDesc, &sockOptionData)); rv = (fileDesc->methods->setsocketoption (fileDesc, & sockOptionData)); | |||
300 | ||||
301 | if (rv != PR_SUCCESS) { | |||
302 | PKIX_ERROR(PKIX_UNABLETOSETSOCKETTONONBLOCKING){ { if (pkixLoggersErrors) { pkix_Logger_CheckWithCode(pkixLoggersErrors , PKIX_UNABLETOSETSOCKETTONONBLOCKING, ((void*)0), stdVars.aPkixType , 2, plContext); } } stdVars.aPkixErrorReceived = ((PKIX_Boolean ) 1); stdVars.aPkixErrorCode = PKIX_UNABLETOSETSOCKETTONONBLOCKING ; goto cleanup; }; | |||
303 | } | |||
304 | cleanup: | |||
305 | ||||
306 | PKIX_RETURN(SOCKET)return PKIX_DoReturn(&stdVars, (PKIX_SOCKET_ERROR), ((PKIX_Boolean ) 1), plContext);; | |||
307 | } | |||
308 | ||||
309 | /* | |||
310 | * FUNCTION: pkix_pl_Socket_CreateClient | |||
311 | * DESCRIPTION: | |||
312 | * | |||
313 | * This functions creates a client socket for the PKIX_PL_Socket pointed to | |||
314 | * by "socket". If "socket" was created with a timeout value of zero, the | |||
315 | * client socket is set to use nonblocking I/O. | |||
316 | * | |||
317 | * PARAMETERS: | |||
318 | * "socket" | |||
319 | * The address of the Socket for which a client socket is to be | |||
320 | * created. Must be non-NULL. | |||
321 | * "plContext" | |||
322 | * Platform-specific context pointer | |||
323 | * THREAD SAFETY: | |||
324 | * Thread Safe (see Thread Safety definitions in Programmer's Guide) | |||
325 | * RETURNS: | |||
326 | * none | |||
327 | */ | |||
328 | ||||
329 | static PKIX_Error * | |||
330 | pkix_pl_Socket_CreateClient( | |||
331 | PKIX_PL_Socket *socket, | |||
332 | void *plContext) | |||
333 | { | |||
334 | #ifdef PKIX_SOCKETDEBUG | |||
335 | PRErrorCode errorcode = 0; | |||
336 | #endif | |||
337 | PRFileDesc *mySock = NULL((void*)0); | |||
338 | ||||
339 | PKIX_ENTER(SOCKET, "pkix_pl_Socket_CreateClient")static const char cMyFuncName[] = {"pkix_pl_Socket_CreateClient" }; PKIX_StdVars stdVars = zeroStdVars; stdVars.aMyFuncName = cMyFuncName ; stdVars.aPkixType = PKIX_SOCKET_ERROR; ; do { if (pkixLoggersDebugTrace ) { pkix_Logger_Check(pkixLoggersDebugTrace, stdVars.aMyFuncName , ">>>", stdVars.aPkixType, 5, plContext); } } while (0);; | |||
340 | PKIX_NULLCHECK_ONE(socket)do { if ((socket) == ((void*)0)){ stdVars.aPkixErrorReceived = ((PKIX_Boolean) 1); stdVars.aPkixErrorCode = PKIX_NULLARGUMENT ; return PKIX_DoReturn(&stdVars, (PKIX_FATAL_ERROR), ((PKIX_Boolean ) 1), plContext);; } } while (0); | |||
341 | ||||
342 | PKIX_PL_NSSCALLRV(SOCKET, mySock, PR_NewTCPSocket, ()); mySock = (PR_NewTCPSocket ()); | |||
343 | if (!mySock) { | |||
344 | #ifdef PKIX_SOCKETDEBUG | |||
345 | errorcode = PR_GetError(); | |||
346 | printf | |||
347 | ("pkix_pl_Socket_CreateClient: %s\n", | |||
348 | PR_ErrorToString(errorcode, PR_LANGUAGE_EN1)); | |||
349 | #endif | |||
350 | PKIX_ERROR(PKIX_PRNEWTCPSOCKETFAILED){ { if (pkixLoggersErrors) { pkix_Logger_CheckWithCode(pkixLoggersErrors , PKIX_PRNEWTCPSOCKETFAILED, ((void*)0), stdVars.aPkixType, 2 , plContext); } } stdVars.aPkixErrorReceived = ((PKIX_Boolean ) 1); stdVars.aPkixErrorCode = PKIX_PRNEWTCPSOCKETFAILED; goto cleanup; }; | |||
351 | } | |||
352 | ||||
353 | #ifdef PKIX_SOCKETDEBUG | |||
354 | printf("Created socket, PRFileDesc @ %#X\n", mySock); | |||
355 | #endif | |||
356 | ||||
357 | socket->clientSock = mySock; | |||
358 | socket->status = SOCKET_UNCONNECTED; | |||
359 | if (socket->timeout == 0) { | |||
360 | PKIX_CHECK(pkix_pl_Socket_SetNonBlocking(mySock, plContext),do { stdVars.aPkixErrorResult = (pkix_pl_Socket_SetNonBlocking (mySock, plContext)); if (stdVars.aPkixErrorResult) { stdVars .aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars .aPkixErrorCode = PKIX_SOCKETSETNONBLOCKINGFAILED; goto cleanup ; } } while (0) | |||
361 | PKIX_SOCKETSETNONBLOCKINGFAILED)do { stdVars.aPkixErrorResult = (pkix_pl_Socket_SetNonBlocking (mySock, plContext)); if (stdVars.aPkixErrorResult) { stdVars .aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars .aPkixErrorCode = PKIX_SOCKETSETNONBLOCKINGFAILED; goto cleanup ; } } while (0); | |||
362 | } | |||
363 | ||||
364 | cleanup: | |||
365 | ||||
366 | PKIX_RETURN(SOCKET)return PKIX_DoReturn(&stdVars, (PKIX_SOCKET_ERROR), ((PKIX_Boolean ) 1), plContext);; | |||
367 | } | |||
368 | ||||
369 | /* | |||
370 | * FUNCTION: pkix_pl_Socket_CreateServer | |||
371 | * DESCRIPTION: | |||
372 | * | |||
373 | * This functions creates a server socket for the PKIX_PL_Socket pointed to | |||
374 | * by "socket". If "socket" was created with a timeout value of zero, the | |||
375 | * server socket is set to use nonblocking I/O. | |||
376 | * | |||
377 | * Warning: there seems to be a problem with operating a server socket in | |||
378 | * non-blocking mode. If the server calls Recv prior to a corresponding | |||
379 | * Send, the message may be lost. | |||
380 | * | |||
381 | * PARAMETERS: | |||
382 | * "socket" | |||
383 | * The address of the Socket for which a server socket is to be | |||
384 | * created. Must be non-NULL. | |||
385 | * "plContext" | |||
386 | * Platform-specific context pointer | |||
387 | * THREAD SAFETY: | |||
388 | * Thread Safe (see Thread Safety definitions in Programmer's Guide) | |||
389 | * RETURNS: | |||
390 | * none | |||
391 | */ | |||
392 | static PKIX_Error * | |||
393 | pkix_pl_Socket_CreateServer( | |||
394 | PKIX_PL_Socket *socket, | |||
395 | void *plContext) | |||
396 | { | |||
397 | /* #ifdef PKIX_SOCKETDEBUG */ | |||
398 | PRErrorCode errorcode = 0; | |||
399 | /* #endif */ | |||
400 | PRStatus rv = PR_FAILURE; | |||
401 | PRFileDesc *serverSock = NULL((void*)0); | |||
402 | PRSocketOptionData sockOptionData; | |||
403 | ||||
404 | PKIX_ENTER(SOCKET, "pkix_pl_Socket_CreateServer")static const char cMyFuncName[] = {"pkix_pl_Socket_CreateServer" }; PKIX_StdVars stdVars = zeroStdVars; stdVars.aMyFuncName = cMyFuncName ; stdVars.aPkixType = PKIX_SOCKET_ERROR; ; do { if (pkixLoggersDebugTrace ) { pkix_Logger_Check(pkixLoggersDebugTrace, stdVars.aMyFuncName , ">>>", stdVars.aPkixType, 5, plContext); } } while (0);; | |||
405 | PKIX_NULLCHECK_ONE(socket)do { if ((socket) == ((void*)0)){ stdVars.aPkixErrorReceived = ((PKIX_Boolean) 1); stdVars.aPkixErrorCode = PKIX_NULLARGUMENT ; return PKIX_DoReturn(&stdVars, (PKIX_FATAL_ERROR), ((PKIX_Boolean ) 1), plContext);; } } while (0); | |||
406 | ||||
407 | PKIX_PL_NSSCALLRV(SOCKET, serverSock, PR_NewTCPSocket, ()); serverSock = (PR_NewTCPSocket ()); | |||
408 | if (!serverSock) { | |||
409 | #ifdef PKIX_SOCKETDEBUG | |||
410 | errorcode = PR_GetError(); | |||
411 | printf | |||
412 | ("pkix_pl_Socket_CreateServer: %s\n", | |||
413 | PR_ErrorToString(errorcode, PR_LANGUAGE_EN1)); | |||
414 | #endif | |||
415 | PKIX_ERROR(PKIX_PRNEWTCPSOCKETFAILED){ { if (pkixLoggersErrors) { pkix_Logger_CheckWithCode(pkixLoggersErrors , PKIX_PRNEWTCPSOCKETFAILED, ((void*)0), stdVars.aPkixType, 2 , plContext); } } stdVars.aPkixErrorReceived = ((PKIX_Boolean ) 1); stdVars.aPkixErrorCode = PKIX_PRNEWTCPSOCKETFAILED; goto cleanup; }; | |||
416 | } | |||
417 | ||||
418 | socket->serverSock = serverSock; | |||
419 | ||||
420 | #ifdef PKIX_SOCKETDEBUG | |||
421 | printf("Created socket, PRFileDesc @ %#X\n", serverSock); | |||
422 | #endif | |||
423 | ||||
424 | if (socket->timeout == 0) { | |||
425 | PKIX_CHECK(pkix_pl_Socket_SetNonBlocking(serverSock, plContext),do { stdVars.aPkixErrorResult = (pkix_pl_Socket_SetNonBlocking (serverSock, plContext)); if (stdVars.aPkixErrorResult) { stdVars .aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars .aPkixErrorCode = PKIX_SOCKETSETNONBLOCKINGFAILED; goto cleanup ; } } while (0) | |||
426 | PKIX_SOCKETSETNONBLOCKINGFAILED)do { stdVars.aPkixErrorResult = (pkix_pl_Socket_SetNonBlocking (serverSock, plContext)); if (stdVars.aPkixErrorResult) { stdVars .aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars .aPkixErrorCode = PKIX_SOCKETSETNONBLOCKINGFAILED; goto cleanup ; } } while (0); | |||
427 | } | |||
428 | ||||
429 | sockOptionData.option = PR_SockOpt_Reuseaddr; | |||
430 | sockOptionData.value.reuse_addr = PR_TRUE1; | |||
431 | ||||
432 | PKIX_PL_NSSCALLRV(SOCKET, rv, serverSock->methods->setsocketoption,; rv = (serverSock->methods->setsocketoption (serverSock , &sockOptionData)) | |||
433 | (serverSock, &sockOptionData)); rv = (serverSock->methods->setsocketoption (serverSock , &sockOptionData)); | |||
434 | ||||
435 | if (rv != PR_SUCCESS) { | |||
436 | PKIX_ERROR(PKIX_UNABLETOSETSOCKETTONONBLOCKING){ { if (pkixLoggersErrors) { pkix_Logger_CheckWithCode(pkixLoggersErrors , PKIX_UNABLETOSETSOCKETTONONBLOCKING, ((void*)0), stdVars.aPkixType , 2, plContext); } } stdVars.aPkixErrorReceived = ((PKIX_Boolean ) 1); stdVars.aPkixErrorCode = PKIX_UNABLETOSETSOCKETTONONBLOCKING ; goto cleanup; }; | |||
437 | } | |||
438 | ||||
439 | PKIX_PL_NSSCALLRV(SOCKET, rv, PR_Bind, (serverSock, socket->netAddr)); rv = (PR_Bind (serverSock, socket->netAddr)); | |||
440 | ||||
441 | if (rv == PR_FAILURE) { | |||
442 | /* #ifdef PKIX_SOCKETDEBUG */ | |||
443 | errorcode = PR_GetError(); | |||
444 | printf | |||
445 | ("pkix_pl_Socket_CreateServer: %s\n", | |||
446 | PR_ErrorToString(errorcode, PR_LANGUAGE_EN1)); | |||
447 | /* #endif */ | |||
448 | PKIX_ERROR(PKIX_PRBINDFAILED){ { if (pkixLoggersErrors) { pkix_Logger_CheckWithCode(pkixLoggersErrors , PKIX_PRBINDFAILED, ((void*)0), stdVars.aPkixType, 2, plContext ); } } stdVars.aPkixErrorReceived = ((PKIX_Boolean) 1); stdVars .aPkixErrorCode = PKIX_PRBINDFAILED; goto cleanup; }; | |||
449 | } | |||
450 | ||||
451 | #ifdef PKIX_SOCKETDEBUG | |||
452 | printf("Successful bind!\n"); | |||
453 | #endif | |||
454 | ||||
455 | socket->status = SOCKET_BOUND; | |||
456 | ||||
457 | cleanup: | |||
458 | ||||
459 | PKIX_RETURN(SOCKET)return PKIX_DoReturn(&stdVars, (PKIX_SOCKET_ERROR), ((PKIX_Boolean ) 1), plContext);; | |||
460 | } | |||
461 | ||||
462 | /* | |||
463 | * FUNCTION: pkix_pl_Socket_Connect | |||
464 | * DESCRIPTION: | |||
465 | * | |||
466 | * This functions performs the connect function for the client socket | |||
467 | * specified in "socket", storing the status at "pStatus". | |||
468 | * | |||
469 | * PARAMETERS: | |||
470 | * "socket" | |||
471 | * The address of the Socket for which a connect is to be performed. | |||
472 | * Must be non-NULL. | |||
473 | * "pStatus" | |||
474 | * The address at which the connection status is stored. Must be non-NULL. | |||
475 | * "plContext" | |||
476 | * Platform-specific context pointer | |||
477 | * THREAD SAFETY: | |||
478 | * Thread Safe (see Thread Safety definitions in Programmer's Guide) | |||
479 | * RETURNS: | |||
480 | * none | |||
481 | */ | |||
482 | static PKIX_Error * | |||
483 | pkix_pl_Socket_Connect( | |||
484 | PKIX_PL_Socket *socket, | |||
485 | PRErrorCode *pStatus, | |||
486 | void *plContext) | |||
487 | { | |||
488 | PRStatus rv = PR_FAILURE; | |||
489 | PRErrorCode errorcode = 0; | |||
490 | ||||
491 | PKIX_ENTER(SOCKET, "pkix_pl_Socket_Connect")static const char cMyFuncName[] = {"pkix_pl_Socket_Connect"}; PKIX_StdVars stdVars = zeroStdVars; stdVars.aMyFuncName = cMyFuncName ; stdVars.aPkixType = PKIX_SOCKET_ERROR; ; do { if (pkixLoggersDebugTrace ) { pkix_Logger_Check(pkixLoggersDebugTrace, stdVars.aMyFuncName , ">>>", stdVars.aPkixType, 5, plContext); } } while (0);; | |||
492 | PKIX_NULLCHECK_TWO(socket, socket->clientSock)do { if (((socket) == ((void*)0)) || ((socket->clientSock) == ((void*)0))){ stdVars.aPkixErrorReceived = ((PKIX_Boolean ) 1); stdVars.aPkixErrorCode = PKIX_NULLARGUMENT; return PKIX_DoReturn (&stdVars, (PKIX_FATAL_ERROR), ((PKIX_Boolean) 1), plContext );; } } while (0); | |||
493 | ||||
494 | PKIX_PL_NSSCALLRV(SOCKET, rv, PR_Connect,; rv = (PR_Connect (socket->clientSock, socket->netAddr , socket->timeout)) | |||
495 | (socket->clientSock, socket->netAddr, socket->timeout)); rv = (PR_Connect (socket->clientSock, socket->netAddr , socket->timeout)); | |||
496 | ||||
497 | if (rv == PR_FAILURE) { | |||
498 | errorcode = PR_GetError(); | |||
499 | *pStatus = errorcode; | |||
500 | if (errorcode == PR_IN_PROGRESS_ERROR(-5934L)) { | |||
501 | socket->status = SOCKET_CONNECTPENDING; | |||
502 | goto cleanup; | |||
503 | } else { | |||
504 | #ifdef PKIX_SOCKETDEBUG | |||
505 | printf | |||
506 | ("pkix_pl_Socket_Connect: %s\n", | |||
507 | PR_ErrorToString(errorcode, PR_LANGUAGE_EN1)); | |||
508 | #endif | |||
509 | PKIX_ERROR(PKIX_PRCONNECTFAILED){ { if (pkixLoggersErrors) { pkix_Logger_CheckWithCode(pkixLoggersErrors , PKIX_PRCONNECTFAILED, ((void*)0), stdVars.aPkixType, 2, plContext ); } } stdVars.aPkixErrorReceived = ((PKIX_Boolean) 1); stdVars .aPkixErrorCode = PKIX_PRCONNECTFAILED; goto cleanup; }; | |||
510 | } | |||
511 | } | |||
512 | ||||
513 | #ifdef PKIX_SOCKETDEBUG | |||
514 | printf("Successful connect!\n"); | |||
515 | #endif | |||
516 | ||||
517 | *pStatus = 0; | |||
518 | socket->status = SOCKET_CONNECTED; | |||
519 | ||||
520 | cleanup: | |||
521 | ||||
522 | PKIX_RETURN(SOCKET)return PKIX_DoReturn(&stdVars, (PKIX_SOCKET_ERROR), ((PKIX_Boolean ) 1), plContext);; | |||
523 | } | |||
524 | ||||
525 | /* | |||
526 | * FUNCTION: pkix_pl_Socket_ConnectContinue | |||
527 | * DESCRIPTION: | |||
528 | * | |||
529 | * This functions continues the connect function for the client socket | |||
530 | * specified in "socket", storing the status at "pStatus". It is expected that | |||
531 | * the non-blocking connect has returned PR_IN_PROGRESS_ERROR. | |||
532 | * | |||
533 | * PARAMETERS: | |||
534 | * "socket" | |||
535 | * The address of the Socket for which a connect is to be continued. | |||
536 | * Must be non-NULL. | |||
537 | * "pStatus" | |||
538 | * The address at which the connection status is stored. Must be non-NULL. | |||
539 | * "plContext" | |||
540 | * Platform-specific context pointer | |||
541 | * THREAD SAFETY: | |||
542 | * Thread Safe (see Thread Safety definitions in Programmer's Guide) | |||
543 | * RETURNS: | |||
544 | * none | |||
545 | */ | |||
546 | static PKIX_Error * | |||
547 | pkix_pl_Socket_ConnectContinue( | |||
548 | PKIX_PL_Socket *socket, | |||
549 | PRErrorCode *pStatus, | |||
550 | void *plContext) | |||
551 | { | |||
552 | PRStatus rv = PR_FAILURE; | |||
553 | PRErrorCode errorcode = 0; | |||
554 | PRPollDesc pollDesc; | |||
555 | PRInt32 numEvents = 0; | |||
556 | ||||
557 | PKIX_ENTER(SOCKET, "pkix_pl_Socket_ConnectContinue")static const char cMyFuncName[] = {"pkix_pl_Socket_ConnectContinue" }; PKIX_StdVars stdVars = zeroStdVars; stdVars.aMyFuncName = cMyFuncName ; stdVars.aPkixType = PKIX_SOCKET_ERROR; ; do { if (pkixLoggersDebugTrace ) { pkix_Logger_Check(pkixLoggersDebugTrace, stdVars.aMyFuncName , ">>>", stdVars.aPkixType, 5, plContext); } } while (0);; | |||
558 | PKIX_NULLCHECK_TWO(socket, socket->clientSock)do { if (((socket) == ((void*)0)) || ((socket->clientSock) == ((void*)0))){ stdVars.aPkixErrorReceived = ((PKIX_Boolean ) 1); stdVars.aPkixErrorCode = PKIX_NULLARGUMENT; return PKIX_DoReturn (&stdVars, (PKIX_FATAL_ERROR), ((PKIX_Boolean) 1), plContext );; } } while (0); | |||
559 | ||||
560 | pollDesc.fd = socket->clientSock; | |||
561 | pollDesc.in_flags = PR_POLL_WRITE0x2 | PR_POLL_EXCEPT0x4; | |||
562 | pollDesc.out_flags = 0; | |||
563 | PKIX_PL_NSSCALLRV(SOCKET, numEvents, PR_Poll, (&pollDesc, 1, 0)); numEvents = (PR_Poll (&pollDesc, 1, 0)); | |||
564 | if (numEvents < 0) { | |||
565 | PKIX_ERROR(PKIX_PRPOLLFAILED){ { if (pkixLoggersErrors) { pkix_Logger_CheckWithCode(pkixLoggersErrors , PKIX_PRPOLLFAILED, ((void*)0), stdVars.aPkixType, 2, plContext ); } } stdVars.aPkixErrorReceived = ((PKIX_Boolean) 1); stdVars .aPkixErrorCode = PKIX_PRPOLLFAILED; goto cleanup; }; | |||
566 | } | |||
567 | ||||
568 | if (numEvents == 0) { | |||
569 | *pStatus = PR_IN_PROGRESS_ERROR(-5934L); | |||
570 | goto cleanup; | |||
571 | } | |||
572 | ||||
573 | PKIX_PL_NSSCALLRV(SOCKET, rv, PR_ConnectContinue,; rv = (PR_ConnectContinue (socket->clientSock, pollDesc.out_flags )) | |||
574 | (socket->clientSock, pollDesc.out_flags)); rv = (PR_ConnectContinue (socket->clientSock, pollDesc.out_flags )); | |||
575 | ||||
576 | /* | |||
577 | * PR_ConnectContinue sometimes lies. It returns PR_SUCCESS | |||
578 | * even though the connection is not yet ready. But its deceit | |||
579 | * is betrayed by the contents of out_flags! | |||
580 | */ | |||
581 | if ((rv == PR_SUCCESS) && (pollDesc.out_flags == PR_POLL_ERR0x8)) { | |||
582 | *pStatus = PR_IN_PROGRESS_ERROR(-5934L); | |||
583 | goto cleanup; | |||
584 | } | |||
585 | ||||
586 | if (rv == PR_FAILURE) { | |||
587 | errorcode = PR_GetError(); | |||
588 | *pStatus = errorcode; | |||
589 | if (errorcode == PR_IN_PROGRESS_ERROR(-5934L)) { | |||
590 | goto cleanup; | |||
591 | } else { | |||
592 | #ifdef PKIX_SOCKETDEBUG | |||
593 | printf | |||
594 | ("pkix_pl_Socket_ConnectContinue: %s\n", | |||
595 | PR_ErrorToString(errorcode, PR_LANGUAGE_EN1)); | |||
596 | #endif | |||
597 | PKIX_ERROR(PKIX_PRCONNECTCONTINUEFAILED){ { if (pkixLoggersErrors) { pkix_Logger_CheckWithCode(pkixLoggersErrors , PKIX_PRCONNECTCONTINUEFAILED, ((void*)0), stdVars.aPkixType , 2, plContext); } } stdVars.aPkixErrorReceived = ((PKIX_Boolean ) 1); stdVars.aPkixErrorCode = PKIX_PRCONNECTCONTINUEFAILED; goto cleanup; }; | |||
598 | } | |||
599 | } | |||
600 | ||||
601 | #ifdef PKIX_SOCKETDEBUG | |||
602 | printf("Successful connect!\n"); | |||
603 | #endif | |||
604 | ||||
605 | *pStatus = 0; | |||
606 | socket->status = SOCKET_CONNECTED; | |||
607 | ||||
608 | cleanup: | |||
609 | ||||
610 | PKIX_RETURN(SOCKET)return PKIX_DoReturn(&stdVars, (PKIX_SOCKET_ERROR), ((PKIX_Boolean ) 1), plContext);; | |||
611 | } | |||
612 | ||||
613 | /* | |||
614 | * FUNCTION: pkix_pl_Socket_Destroy | |||
615 | * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h) | |||
616 | */ | |||
617 | static PKIX_Error * | |||
618 | pkix_pl_Socket_Destroy( | |||
619 | PKIX_PL_Object *object, | |||
620 | void *plContext) | |||
621 | { | |||
622 | PKIX_PL_Socket *socket = NULL((void*)0); | |||
623 | ||||
624 | PKIX_ENTER(SOCKET, "pkix_pl_Socket_Destroy")static const char cMyFuncName[] = {"pkix_pl_Socket_Destroy"}; PKIX_StdVars stdVars = zeroStdVars; stdVars.aMyFuncName = cMyFuncName ; stdVars.aPkixType = PKIX_SOCKET_ERROR; ; do { if (pkixLoggersDebugTrace ) { pkix_Logger_Check(pkixLoggersDebugTrace, stdVars.aMyFuncName , ">>>", stdVars.aPkixType, 5, plContext); } } while (0);; | |||
625 | PKIX_NULLCHECK_ONE(object)do { if ((object) == ((void*)0)){ stdVars.aPkixErrorReceived = ((PKIX_Boolean) 1); stdVars.aPkixErrorCode = PKIX_NULLARGUMENT ; return PKIX_DoReturn(&stdVars, (PKIX_FATAL_ERROR), ((PKIX_Boolean ) 1), plContext);; } } while (0); | |||
626 | ||||
627 | PKIX_CHECK(pkix_CheckTypedo { stdVars.aPkixErrorResult = (pkix_CheckType (object, PKIX_SOCKET_TYPE , plContext)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode = PKIX_OBJECTNOTANSOCKET; goto cleanup; } } while (0) | |||
628 | (object, PKIX_SOCKET_TYPE, plContext),do { stdVars.aPkixErrorResult = (pkix_CheckType (object, PKIX_SOCKET_TYPE , plContext)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode = PKIX_OBJECTNOTANSOCKET; goto cleanup; } } while (0) | |||
629 | PKIX_OBJECTNOTANSOCKET)do { stdVars.aPkixErrorResult = (pkix_CheckType (object, PKIX_SOCKET_TYPE , plContext)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode = PKIX_OBJECTNOTANSOCKET; goto cleanup; } } while (0); | |||
630 | ||||
631 | socket = (PKIX_PL_Socket *)object; | |||
632 | ||||
633 | if (socket->isServer) { | |||
634 | if (socket->serverSock) { | |||
635 | PR_Close(socket->serverSock); | |||
636 | } | |||
637 | } else { | |||
638 | if (socket->clientSock) { | |||
639 | PR_Close(socket->clientSock); | |||
640 | } | |||
641 | } | |||
642 | ||||
643 | cleanup: | |||
644 | ||||
645 | PKIX_RETURN(SOCKET)return PKIX_DoReturn(&stdVars, (PKIX_SOCKET_ERROR), ((PKIX_Boolean ) 1), plContext);; | |||
646 | } | |||
647 | ||||
648 | /* | |||
649 | * FUNCTION: pkix_pl_Socket_Hashcode | |||
650 | * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h) | |||
651 | */ | |||
652 | static PKIX_Error * | |||
653 | pkix_pl_Socket_Hashcode( | |||
654 | PKIX_PL_Object *object, | |||
655 | PKIX_UInt32 *pHashcode, | |||
656 | void *plContext) | |||
657 | { | |||
658 | PKIX_PL_Socket *socket = NULL((void*)0); | |||
659 | ||||
660 | PKIX_ENTER(SOCKET, "pkix_pl_Socket_Hashcode")static const char cMyFuncName[] = {"pkix_pl_Socket_Hashcode"} ; PKIX_StdVars stdVars = zeroStdVars; stdVars.aMyFuncName = cMyFuncName ; stdVars.aPkixType = PKIX_SOCKET_ERROR; ; do { if (pkixLoggersDebugTrace ) { pkix_Logger_Check(pkixLoggersDebugTrace, stdVars.aMyFuncName , ">>>", stdVars.aPkixType, 5, plContext); } } while (0);; | |||
661 | PKIX_NULLCHECK_TWO(object, pHashcode)do { if (((object) == ((void*)0)) || ((pHashcode) == ((void*) 0))){ stdVars.aPkixErrorReceived = ((PKIX_Boolean) 1); stdVars .aPkixErrorCode = PKIX_NULLARGUMENT; return PKIX_DoReturn(& stdVars, (PKIX_FATAL_ERROR), ((PKIX_Boolean) 1), plContext);; } } while (0); | |||
662 | ||||
663 | PKIX_CHECK(pkix_CheckType(object, PKIX_SOCKET_TYPE, plContext),do { stdVars.aPkixErrorResult = (pkix_CheckType(object, PKIX_SOCKET_TYPE , plContext)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode = PKIX_OBJECTNOTSOCKET; goto cleanup; } } while (0) | |||
664 | PKIX_OBJECTNOTSOCKET)do { stdVars.aPkixErrorResult = (pkix_CheckType(object, PKIX_SOCKET_TYPE , plContext)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode = PKIX_OBJECTNOTSOCKET; goto cleanup; } } while (0); | |||
665 | ||||
666 | socket = (PKIX_PL_Socket *)object; | |||
667 | ||||
668 | *pHashcode = (((socket->timeout << 3) + | |||
669 | (socket->netAddr->inet.family << 3)) + | |||
670 | (*((PKIX_UInt32 *)&(socket->netAddr->inet.ip)))) + | |||
671 | socket->netAddr->inet.port; | |||
672 | ||||
673 | cleanup: | |||
674 | ||||
675 | PKIX_RETURN(SOCKET)return PKIX_DoReturn(&stdVars, (PKIX_SOCKET_ERROR), ((PKIX_Boolean ) 1), plContext);; | |||
676 | } | |||
677 | ||||
678 | /* | |||
679 | * FUNCTION: pkix_pl_Socket_Equals | |||
680 | * (see comments for PKIX_PL_EqualsCallback in pkix_pl_system.h) | |||
681 | */ | |||
682 | static PKIX_Error * | |||
683 | pkix_pl_Socket_Equals( | |||
684 | PKIX_PL_Object *firstObject, | |||
685 | PKIX_PL_Object *secondObject, | |||
686 | PKIX_Int32 *pResult, | |||
687 | void *plContext) | |||
688 | { | |||
689 | PKIX_PL_Socket *firstSocket = NULL((void*)0); | |||
690 | PKIX_PL_Socket *secondSocket = NULL((void*)0); | |||
691 | ||||
692 | PKIX_ENTER(SOCKET, "pkix_pl_Socket_Equals")static const char cMyFuncName[] = {"pkix_pl_Socket_Equals"}; PKIX_StdVars stdVars = zeroStdVars; stdVars.aMyFuncName = cMyFuncName; stdVars .aPkixType = PKIX_SOCKET_ERROR; ; do { if (pkixLoggersDebugTrace ) { pkix_Logger_Check(pkixLoggersDebugTrace, stdVars.aMyFuncName , ">>>", stdVars.aPkixType, 5, plContext); } } while (0);; | |||
693 | PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult)do { if (((firstObject) == ((void*)0)) || ((secondObject) == ( (void*)0)) || ((pResult) == ((void*)0))){ stdVars.aPkixErrorReceived = ((PKIX_Boolean) 1); stdVars.aPkixErrorCode = PKIX_NULLARGUMENT ; return PKIX_DoReturn(&stdVars, (PKIX_FATAL_ERROR), ((PKIX_Boolean ) 1), plContext);; } } while (0); | |||
694 | ||||
695 | *pResult = PKIX_FALSE((PKIX_Boolean) 0); | |||
696 | ||||
697 | PKIX_CHECK(pkix_CheckTypesdo { stdVars.aPkixErrorResult = (pkix_CheckTypes (firstObject , secondObject, PKIX_SOCKET_TYPE, plContext)); if (stdVars.aPkixErrorResult ) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass ; stdVars.aPkixErrorCode = PKIX_OBJECTNOTSOCKET; goto cleanup ; } } while (0) | |||
698 | (firstObject, secondObject, PKIX_SOCKET_TYPE, plContext),do { stdVars.aPkixErrorResult = (pkix_CheckTypes (firstObject , secondObject, PKIX_SOCKET_TYPE, plContext)); if (stdVars.aPkixErrorResult ) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass ; stdVars.aPkixErrorCode = PKIX_OBJECTNOTSOCKET; goto cleanup ; } } while (0) | |||
699 | PKIX_OBJECTNOTSOCKET)do { stdVars.aPkixErrorResult = (pkix_CheckTypes (firstObject , secondObject, PKIX_SOCKET_TYPE, plContext)); if (stdVars.aPkixErrorResult ) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass ; stdVars.aPkixErrorCode = PKIX_OBJECTNOTSOCKET; goto cleanup ; } } while (0); | |||
700 | ||||
701 | firstSocket = (PKIX_PL_Socket *)firstObject; | |||
702 | secondSocket = (PKIX_PL_Socket *)secondObject; | |||
703 | ||||
704 | if (firstSocket->timeout != secondSocket->timeout) { | |||
705 | goto cleanup; | |||
706 | } | |||
707 | ||||
708 | if (firstSocket->netAddr == secondSocket->netAddr) { | |||
709 | *pResult = PKIX_TRUE((PKIX_Boolean) 1); | |||
710 | goto cleanup; | |||
711 | } | |||
712 | ||||
713 | if ((firstSocket->netAddr->inet.family != | |||
714 | secondSocket->netAddr->inet.family) || | |||
715 | (*((PKIX_UInt32 *)&(firstSocket->netAddr->inet.ip)) != | |||
716 | *((PKIX_UInt32 *)&(secondSocket->netAddr->inet.ip))) || | |||
717 | (firstSocket->netAddr->inet.port != | |||
718 | secondSocket->netAddr->inet.port)) { | |||
719 | ||||
720 | goto cleanup; | |||
721 | ||||
722 | } | |||
723 | ||||
724 | *pResult = PKIX_TRUE((PKIX_Boolean) 1); | |||
725 | ||||
726 | cleanup: | |||
727 | ||||
728 | PKIX_RETURN(SOCKET)return PKIX_DoReturn(&stdVars, (PKIX_SOCKET_ERROR), ((PKIX_Boolean ) 1), plContext);; | |||
729 | } | |||
730 | ||||
731 | /* | |||
732 | * FUNCTION: pkix_pl_Socket_RegisterSelf | |||
733 | * | |||
734 | * DESCRIPTION: | |||
735 | * Registers PKIX_PL_SOCKET_TYPE and its related | |||
736 | * functions with systemClasses[] | |||
737 | * | |||
738 | * THREAD SAFETY: | |||
739 | * Not Thread Safe - for performance and complexity reasons | |||
740 | * | |||
741 | * Since this function is only called by PKIX_PL_Initialize, which should | |||
742 | * only be called once, it is acceptable that this function is not | |||
743 | * thread-safe. | |||
744 | */ | |||
745 | PKIX_Error * | |||
746 | pkix_pl_Socket_RegisterSelf(void *plContext) | |||
747 | { | |||
748 | extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES]; | |||
749 | pkix_ClassTable_Entry entry; | |||
750 | ||||
751 | PKIX_ENTER(SOCKET, "pkix_pl_Socket_RegisterSelf")static const char cMyFuncName[] = {"pkix_pl_Socket_RegisterSelf" }; PKIX_StdVars stdVars = zeroStdVars; stdVars.aMyFuncName = cMyFuncName ; stdVars.aPkixType = PKIX_SOCKET_ERROR; ; do { if (pkixLoggersDebugTrace ) { pkix_Logger_Check(pkixLoggersDebugTrace, stdVars.aMyFuncName , ">>>", stdVars.aPkixType, 5, plContext); } } while (0);; | |||
752 | ||||
753 | entry.description = "Socket"; | |||
754 | entry.objCounter = 0; | |||
755 | entry.typeObjectSize = sizeof(PKIX_PL_Socket); | |||
756 | entry.destructor = pkix_pl_Socket_Destroy; | |||
757 | entry.equalsFunction = pkix_pl_Socket_Equals; | |||
758 | entry.hashcodeFunction = pkix_pl_Socket_Hashcode; | |||
759 | entry.toStringFunction = NULL((void*)0); | |||
760 | entry.comparator = NULL((void*)0); | |||
761 | entry.duplicateFunction = NULL((void*)0); | |||
762 | ||||
763 | systemClasses[PKIX_SOCKET_TYPE] = entry; | |||
764 | ||||
765 | #ifdef PKIX_SOCKETTRACE1 | |||
766 | { | |||
767 | char *val = NULL((void*)0); | |||
768 | val = PR_GetEnvSecure("SOCKETTRACE"); | |||
769 | /* Is SOCKETTRACE set in the environment? */ | |||
770 | if ((val != NULL((void*)0)) && (*val != '\0')) { | |||
771 | socketTraceFlag = | |||
772 | ((*val == '1')?PKIX_TRUE((PKIX_Boolean) 1):PKIX_FALSE((PKIX_Boolean) 0)); | |||
773 | } | |||
774 | } | |||
775 | #endif | |||
776 | ||||
777 | PKIX_RETURN(SOCKET)return PKIX_DoReturn(&stdVars, (PKIX_SOCKET_ERROR), ((PKIX_Boolean ) 1), plContext);; | |||
778 | } | |||
779 | ||||
780 | /* --Public-Socket-Functions----------------------------------- */ | |||
781 | ||||
782 | /* | |||
783 | * FUNCTION: pkix_pl_Socket_Listen | |||
784 | * DESCRIPTION: | |||
785 | * | |||
786 | * This functions establishes a listening queue for the server Socket | |||
787 | * pointed to by "socket". | |||
788 | * | |||
789 | * PARAMETERS: | |||
790 | * "socket" | |||
791 | * The address of the server socket for which the queue is to be | |||
792 | * established. Must be non-NULL. | |||
793 | * "backlog" | |||
794 | * The UInt32 value of the length of the queue to be established. | |||
795 | * "plContext" | |||
796 | * Platform-specific context pointer | |||
797 | * THREAD SAFETY: | |||
798 | * Thread Safe (see Thread Safety definitions in Programmer's Guide) | |||
799 | * RETURNS: | |||
800 | * none | |||
801 | */ | |||
802 | static PKIX_Error * | |||
803 | pkix_pl_Socket_Listen( | |||
804 | PKIX_PL_Socket *socket, | |||
805 | PKIX_UInt32 backlog, | |||
806 | void *plContext) | |||
807 | { | |||
808 | #ifdef PKIX_SOCKETDEBUG | |||
809 | PRErrorCode errorcode = 0; | |||
810 | #endif | |||
811 | PRStatus rv = PR_FAILURE; | |||
812 | ||||
813 | PKIX_ENTER(SOCKET, "pkix_pl_Socket_Listen")static const char cMyFuncName[] = {"pkix_pl_Socket_Listen"}; PKIX_StdVars stdVars = zeroStdVars; stdVars.aMyFuncName = cMyFuncName; stdVars .aPkixType = PKIX_SOCKET_ERROR; ; do { if (pkixLoggersDebugTrace ) { pkix_Logger_Check(pkixLoggersDebugTrace, stdVars.aMyFuncName , ">>>", stdVars.aPkixType, 5, plContext); } } while (0);; | |||
814 | PKIX_NULLCHECK_TWO(socket, socket->serverSock)do { if (((socket) == ((void*)0)) || ((socket->serverSock) == ((void*)0))){ stdVars.aPkixErrorReceived = ((PKIX_Boolean ) 1); stdVars.aPkixErrorCode = PKIX_NULLARGUMENT; return PKIX_DoReturn (&stdVars, (PKIX_FATAL_ERROR), ((PKIX_Boolean) 1), plContext );; } } while (0); | |||
815 | ||||
816 | PKIX_PL_NSSCALLRV(SOCKET, rv, PR_Listen,; rv = (PR_Listen (socket->serverSock, (PRIntn)backlog)) | |||
817 | (socket->serverSock, (PRIntn)backlog)); rv = (PR_Listen (socket->serverSock, (PRIntn)backlog)); | |||
818 | ||||
819 | if (rv == PR_FAILURE) { | |||
820 | #ifdef PKIX_SOCKETDEBUG | |||
821 | errorcode = PR_GetError(); | |||
822 | printf | |||
823 | ("pkix_pl_Socket_Listen: %s\n", | |||
824 | PR_ErrorToString(errorcode, PR_LANGUAGE_EN1)); | |||
825 | #endif | |||
826 | PKIX_ERROR(PKIX_PRLISTENFAILED){ { if (pkixLoggersErrors) { pkix_Logger_CheckWithCode(pkixLoggersErrors , PKIX_PRLISTENFAILED, ((void*)0), stdVars.aPkixType, 2, plContext ); } } stdVars.aPkixErrorReceived = ((PKIX_Boolean) 1); stdVars .aPkixErrorCode = PKIX_PRLISTENFAILED; goto cleanup; }; | |||
827 | } | |||
828 | ||||
829 | #ifdef PKIX_SOCKETDEBUG | |||
830 | printf("Successful listen!\n"); | |||
831 | #endif | |||
832 | ||||
833 | socket->status = SOCKET_LISTENING; | |||
834 | cleanup: | |||
835 | ||||
836 | PKIX_RETURN(SOCKET)return PKIX_DoReturn(&stdVars, (PKIX_SOCKET_ERROR), ((PKIX_Boolean ) 1), plContext);; | |||
837 | } | |||
838 | ||||
839 | /* | |||
840 | * FUNCTION: pkix_pl_Socket_Shutdown | |||
841 | * DESCRIPTION: | |||
842 | * | |||
843 | * This functions performs the shutdown of any connections controlled by the | |||
844 | * socket pointed to by "socket". | |||
845 | * | |||
846 | * PARAMETERS: | |||
847 | * "socket" | |||
848 | * The address of the socket to be shut down. Must be non-NULL. | |||
849 | * "plContext" | |||
850 | * Platform-specific context pointer | |||
851 | * THREAD SAFETY: | |||
852 | * Thread Safe (see Thread Safety definitions in Programmer's Guide) | |||
853 | * RETURNS: | |||
854 | * none | |||
855 | */ | |||
856 | static PKIX_Error * | |||
857 | pkix_pl_Socket_Shutdown( | |||
858 | PKIX_PL_Socket *socket, | |||
859 | void *plContext) | |||
860 | { | |||
861 | #ifdef PKIX_SOCKETDEBUG | |||
862 | PRErrorCode errorcode = 0; | |||
863 | #endif | |||
864 | PRStatus rv = PR_FAILURE; | |||
865 | PRFileDesc *fileDesc = NULL((void*)0); | |||
866 | ||||
867 | PKIX_ENTER(SOCKET, "pkix_pl_Socket_Shutdown")static const char cMyFuncName[] = {"pkix_pl_Socket_Shutdown"} ; PKIX_StdVars stdVars = zeroStdVars; stdVars.aMyFuncName = cMyFuncName ; stdVars.aPkixType = PKIX_SOCKET_ERROR; ; do { if (pkixLoggersDebugTrace ) { pkix_Logger_Check(pkixLoggersDebugTrace, stdVars.aMyFuncName , ">>>", stdVars.aPkixType, 5, plContext); } } while (0);; | |||
868 | PKIX_NULLCHECK_ONE(socket)do { if ((socket) == ((void*)0)){ stdVars.aPkixErrorReceived = ((PKIX_Boolean) 1); stdVars.aPkixErrorCode = PKIX_NULLARGUMENT ; return PKIX_DoReturn(&stdVars, (PKIX_FATAL_ERROR), ((PKIX_Boolean ) 1), plContext);; } } while (0); | |||
869 | ||||
870 | fileDesc = | |||
871 | (socket->isServer)?(socket->serverSock):(socket->clientSock); | |||
872 | ||||
873 | PKIX_PL_NSSCALLRV(SOCKET, rv, PR_Shutdown,; rv = (PR_Shutdown (fileDesc, PR_SHUTDOWN_BOTH)) | |||
874 | (fileDesc, PR_SHUTDOWN_BOTH)); rv = (PR_Shutdown (fileDesc, PR_SHUTDOWN_BOTH)); | |||
875 | ||||
876 | if (rv == PR_FAILURE) { | |||
877 | #ifdef PKIX_SOCKETDEBUG | |||
878 | errorcode = PR_GetError(); | |||
879 | printf | |||
880 | ("pkix_pl_Socket_Shutdown: %s\n", | |||
881 | PR_ErrorToString(errorcode, PR_LANGUAGE_EN1)); | |||
882 | #endif | |||
883 | PKIX_ERROR(PKIX_PRSHUTDOWNFAILED){ { if (pkixLoggersErrors) { pkix_Logger_CheckWithCode(pkixLoggersErrors , PKIX_PRSHUTDOWNFAILED, ((void*)0), stdVars.aPkixType, 2, plContext ); } } stdVars.aPkixErrorReceived = ((PKIX_Boolean) 1); stdVars .aPkixErrorCode = PKIX_PRSHUTDOWNFAILED; goto cleanup; }; | |||
884 | } | |||
885 | socket->status = SOCKET_SHUTDOWN; | |||
886 | ||||
887 | cleanup: | |||
888 | ||||
889 | PKIX_RETURN(SOCKET)return PKIX_DoReturn(&stdVars, (PKIX_SOCKET_ERROR), ((PKIX_Boolean ) 1), plContext);; | |||
890 | } | |||
891 | ||||
892 | /* | |||
893 | * FUNCTION: pkix_pl_Socket_Send | |||
894 | * DESCRIPTION: | |||
895 | * | |||
896 | * This functions sends a message using the socket pointed to by "sendSock", | |||
897 | * from the buffer pointed to by "buf", of the number of bytes given by | |||
898 | * "bytesToWrite", storing the number of bytes actually written at | |||
899 | * "pBytesWritten". If "socket" is in non-blocking mode, the send operation | |||
900 | * may store -1 at "pBytesWritten" and the write is not complete until a | |||
901 | * corresponding pkix_pl_Poll call has indicated its completion by returning | |||
902 | * a non-negative value for bytes written. | |||
903 | * | |||
904 | * PARAMETERS: | |||
905 | * "sendSock" | |||
906 | * The address of the Socket on which the message is to be sent. Must | |||
907 | * be non-NULL. | |||
908 | * "buf" | |||
909 | * The address of the data to be sent. Must be non-NULL. | |||
910 | * "bytesToWrite"" | |||
911 | * The UInt32 value indicating the number of bytes to write. | |||
912 | * "pBytesWritten" | |||
913 | * The address at which the Int32 value indicating the number of bytes | |||
914 | * actually written is to be stored. Must be non-NULL. | |||
915 | * "plContext" | |||
916 | * Platform-specific context pointer | |||
917 | * THREAD SAFETY: | |||
918 | * Thread Safe (see Thread Safety definitions in Programmer's Guide) | |||
919 | * RETURNS: | |||
920 | * none | |||
921 | */ | |||
922 | static PKIX_Error * | |||
923 | pkix_pl_Socket_Send( | |||
924 | PKIX_PL_Socket *sendSock, | |||
925 | void *buf, | |||
926 | PKIX_UInt32 bytesToWrite, | |||
927 | PKIX_Int32 *pBytesWritten, | |||
928 | void *plContext) | |||
929 | { | |||
930 | PRInt32 bytesWritten = 0; | |||
931 | PRErrorCode errorcode = 0; | |||
932 | PRFileDesc *fd = NULL((void*)0); | |||
933 | ||||
934 | PKIX_ENTER(SOCKET, "pkix_pl_Socket_Send")static const char cMyFuncName[] = {"pkix_pl_Socket_Send"}; PKIX_StdVars stdVars = zeroStdVars; stdVars.aMyFuncName = cMyFuncName; stdVars .aPkixType = PKIX_SOCKET_ERROR; ; do { if (pkixLoggersDebugTrace ) { pkix_Logger_Check(pkixLoggersDebugTrace, stdVars.aMyFuncName , ">>>", stdVars.aPkixType, 5, plContext); } } while (0);; | |||
935 | PKIX_NULLCHECK_TWO(buf, pBytesWritten)do { if (((buf) == ((void*)0)) || ((pBytesWritten) == ((void* )0))){ stdVars.aPkixErrorReceived = ((PKIX_Boolean) 1); stdVars .aPkixErrorCode = PKIX_NULLARGUMENT; return PKIX_DoReturn(& stdVars, (PKIX_FATAL_ERROR), ((PKIX_Boolean) 1), plContext);; } } while (0); | |||
936 | ||||
937 | fd = sendSock->clientSock; | |||
938 | ||||
939 | PKIX_PL_NSSCALLRV(SOCKET, bytesWritten, PR_Send,; bytesWritten = (PR_Send (fd, buf, (PRInt32)bytesToWrite, 0, sendSock->timeout)) | |||
940 | (fd, buf, (PRInt32)bytesToWrite, 0, sendSock->timeout)); bytesWritten = (PR_Send (fd, buf, (PRInt32)bytesToWrite, 0, sendSock->timeout)); | |||
941 | ||||
942 | if (bytesWritten >= 0) { | |||
943 | if (sendSock->status == SOCKET_SENDRCVPENDING) { | |||
944 | sendSock->status = SOCKET_RCVPENDING; | |||
945 | } else { | |||
946 | sendSock->status = SOCKET_CONNECTED; | |||
947 | } | |||
948 | #ifdef PKIX_SOCKETTRACE1 | |||
949 | pkix_pl_socket_tracebuff(buf, bytesWritten); | |||
950 | #endif | |||
951 | } else { | |||
952 | errorcode = PR_GetError(); | |||
953 | if (errorcode != PR_WOULD_BLOCK_ERROR(-5998L)) { | |||
954 | #ifdef PKIX_SOCKETDEBUG | |||
955 | printf | |||
956 | ("pkix_pl_Socket_Send: %s\n", | |||
957 | PR_ErrorToString(errorcode, PR_LANGUAGE_EN1)); | |||
958 | #endif | |||
959 | PKIX_ERROR(PKIX_PRSENDFAILED){ { if (pkixLoggersErrors) { pkix_Logger_CheckWithCode(pkixLoggersErrors , PKIX_PRSENDFAILED, ((void*)0), stdVars.aPkixType, 2, plContext ); } } stdVars.aPkixErrorReceived = ((PKIX_Boolean) 1); stdVars .aPkixErrorCode = PKIX_PRSENDFAILED; goto cleanup; }; | |||
960 | } | |||
961 | ||||
962 | sendSock->writeBuf = buf; | |||
963 | sendSock->writeBufSize = bytesToWrite; | |||
964 | if (sendSock->status == SOCKET_RCVPENDING) { | |||
965 | sendSock->status = SOCKET_SENDRCVPENDING; | |||
966 | } else { | |||
967 | sendSock->status = SOCKET_SENDPENDING; | |||
968 | } | |||
969 | } | |||
970 | ||||
971 | *pBytesWritten = (PKIX_Int32)bytesWritten; | |||
972 | ||||
973 | cleanup: | |||
974 | ||||
975 | PKIX_RETURN(SOCKET)return PKIX_DoReturn(&stdVars, (PKIX_SOCKET_ERROR), ((PKIX_Boolean ) 1), plContext);; | |||
976 | } | |||
977 | ||||
978 | /* | |||
979 | * FUNCTION: pkix_pl_Socket_Recv | |||
980 | * DESCRIPTION: | |||
981 | * | |||
982 | * This functions receives a message on the socket pointed to by "rcvSock", | |||
983 | * into the buffer pointed to by "buf", of capacity given by "capacity", | |||
984 | * storing the number of bytes actually received at "pBytesRead". If "socket" | |||
985 | * is in non-blocking mode, the receive operation may store -1 at | |||
986 | * "pBytesWritten". In that case the write is not complete until a | |||
987 | * corresponding pkix_pl_Poll call has indicated its completion by returning | |||
988 | * a non-negative value for bytes read. | |||
989 | * | |||
990 | * PARAMETERS: | |||
991 | * "rcvSock" | |||
992 | * The address of the Socket on which the message is to be received. | |||
993 | * Must be non-NULL. | |||
994 | * "buf" | |||
995 | * The address of the buffer into which the message is to be received. | |||
996 | * Must be non-NULL. | |||
997 | * "capacity" | |||
998 | * The UInt32 value of the size of the buffer; that is, the maximum | |||
999 | * number of bytes that can be received. | |||
1000 | * "pBytesRead" | |||
1001 | * The address at which is stored the Int32 value of the number of bytes | |||
1002 | * actually received. | |||
1003 | * "plContext" | |||
1004 | * Platform-specific context pointer | |||
1005 | * THREAD SAFETY: | |||
1006 | * Thread Safe (see Thread Safety definitions in Programmer's Guide) | |||
1007 | * RETURNS: | |||
1008 | * none | |||
1009 | */ | |||
1010 | static PKIX_Error * | |||
1011 | pkix_pl_Socket_Recv( | |||
1012 | PKIX_PL_Socket *rcvSock, | |||
1013 | void *buf, | |||
1014 | PKIX_UInt32 capacity, | |||
1015 | PKIX_Int32 *pBytesRead, | |||
1016 | void *plContext) | |||
1017 | { | |||
1018 | PRErrorCode errorcode = 0; | |||
1019 | PRInt32 bytesRead = 0; | |||
1020 | PRFileDesc *fd = NULL((void*)0); | |||
1021 | ||||
1022 | PKIX_ENTER(SOCKET, "pkix_pl_Socket_Recv")static const char cMyFuncName[] = {"pkix_pl_Socket_Recv"}; PKIX_StdVars stdVars = zeroStdVars; stdVars.aMyFuncName = cMyFuncName; stdVars .aPkixType = PKIX_SOCKET_ERROR; ; do { if (pkixLoggersDebugTrace ) { pkix_Logger_Check(pkixLoggersDebugTrace, stdVars.aMyFuncName , ">>>", stdVars.aPkixType, 5, plContext); } } while (0);; | |||
1023 | PKIX_NULLCHECK_THREE(rcvSock, buf, pBytesRead)do { if (((rcvSock) == ((void*)0)) || ((buf) == ((void*)0)) || ((pBytesRead) == ((void*)0))){ stdVars.aPkixErrorReceived = ( (PKIX_Boolean) 1); stdVars.aPkixErrorCode = PKIX_NULLARGUMENT ; return PKIX_DoReturn(&stdVars, (PKIX_FATAL_ERROR), ((PKIX_Boolean ) 1), plContext);; } } while (0); | |||
1024 | ||||
1025 | fd = rcvSock->clientSock; | |||
1026 | ||||
1027 | PKIX_PL_NSSCALLRV(SOCKET, bytesRead, PR_Recv,; bytesRead = (PR_Recv (fd, buf, (PRInt32)capacity, 0, rcvSock ->timeout)) | |||
1028 | (fd, buf, (PRInt32)capacity, 0, rcvSock->timeout)); bytesRead = (PR_Recv (fd, buf, (PRInt32)capacity, 0, rcvSock ->timeout)); | |||
1029 | ||||
1030 | if (bytesRead > 0) { | |||
1031 | if (rcvSock->status == SOCKET_SENDRCVPENDING) { | |||
1032 | rcvSock->status = SOCKET_SENDPENDING; | |||
1033 | } else { | |||
1034 | rcvSock->status = SOCKET_CONNECTED; | |||
1035 | } | |||
1036 | #ifdef PKIX_SOCKETTRACE1 | |||
1037 | pkix_pl_socket_tracebuff(buf, bytesRead); | |||
1038 | #endif | |||
1039 | } else if (bytesRead == 0) { | |||
1040 | PKIX_ERROR(PKIX_PRRECVREPORTSNETWORKCONNECTIONCLOSED){ { if (pkixLoggersErrors) { pkix_Logger_CheckWithCode(pkixLoggersErrors , PKIX_PRRECVREPORTSNETWORKCONNECTIONCLOSED, ((void*)0), stdVars .aPkixType, 2, plContext); } } stdVars.aPkixErrorReceived = ( (PKIX_Boolean) 1); stdVars.aPkixErrorCode = PKIX_PRRECVREPORTSNETWORKCONNECTIONCLOSED ; goto cleanup; }; | |||
1041 | } else { | |||
1042 | errorcode = PR_GetError(); | |||
1043 | if (errorcode != PR_WOULD_BLOCK_ERROR(-5998L)) { | |||
1044 | #ifdef PKIX_SOCKETDEBUG | |||
1045 | printf | |||
1046 | ("pkix_pl_Socket_Recv: %s\n", | |||
1047 | PR_ErrorToString(errorcode, PR_LANGUAGE_EN1)); | |||
1048 | #endif | |||
1049 | PKIX_ERROR(PKIX_PRRECVFAILED){ { if (pkixLoggersErrors) { pkix_Logger_CheckWithCode(pkixLoggersErrors , PKIX_PRRECVFAILED, ((void*)0), stdVars.aPkixType, 2, plContext ); } } stdVars.aPkixErrorReceived = ((PKIX_Boolean) 1); stdVars .aPkixErrorCode = PKIX_PRRECVFAILED; goto cleanup; }; | |||
1050 | } | |||
1051 | rcvSock->readBuf = buf; | |||
1052 | rcvSock->readBufSize = capacity; | |||
1053 | if (rcvSock->status == SOCKET_SENDPENDING) { | |||
1054 | rcvSock->status = SOCKET_SENDRCVPENDING; | |||
1055 | } else { | |||
1056 | rcvSock->status = SOCKET_RCVPENDING; | |||
1057 | } | |||
1058 | ||||
1059 | } | |||
1060 | ||||
1061 | *pBytesRead = (PKIX_Int32)bytesRead; | |||
1062 | ||||
1063 | cleanup: | |||
1064 | ||||
1065 | PKIX_RETURN(SOCKET)return PKIX_DoReturn(&stdVars, (PKIX_SOCKET_ERROR), ((PKIX_Boolean ) 1), plContext);; | |||
1066 | } | |||
1067 | ||||
1068 | /* | |||
1069 | * FUNCTION: pkix_pl_Socket_Poll | |||
1070 | * DESCRIPTION: | |||
1071 | * | |||
1072 | * This functions checks for completion of an earlier Send or Recv on the | |||
1073 | * socket pointed to by "sock", storing in "pBytesWritten" the number of bytes | |||
1074 | * written by a completed Send and in "pBytesRead" the number of bytes | |||
1075 | * received in a completed Recv. A value of -1 returned indicates the | |||
1076 | * operation has still not completed. A NULL pointer may be supplied for | |||
1077 | * "pBytesWritten" to avoid checking for completion of a Send. A NULL pointer | |||
1078 | * may be supplied for "pBytesRead" to avoid checking for completion of a Recv. | |||
1079 | * | |||
1080 | * PARAMETERS: | |||
1081 | * "sock" | |||
1082 | * The address of the socket for which completions are to be checked. | |||
1083 | * "pBytesWritten" | |||
1084 | * The address at which the number of bytes written is to be stored, if | |||
1085 | * a pending Send has completed. If NULL, Sends are not checked. | |||
1086 | * "pBytesRead" | |||
1087 | * The address at which the number of bytes read is to be stored, if | |||
1088 | * a pending Recv has completed. If NULL, Recvs are not checked. | |||
1089 | * "plContext" | |||
1090 | * Platform-specific context pointer | |||
1091 | * THREAD SAFETY: | |||
1092 | * Thread Safe (see Thread Safety definitions in Programmer's Guide) | |||
1093 | * RETURNS: | |||
1094 | * none | |||
1095 | */ | |||
1096 | static PKIX_Error * | |||
1097 | pkix_pl_Socket_Poll( | |||
1098 | PKIX_PL_Socket *sock, | |||
1099 | PKIX_Int32 *pBytesWritten, | |||
1100 | PKIX_Int32 *pBytesRead, | |||
1101 | void *plContext) | |||
1102 | { | |||
1103 | PRPollDesc pollDesc; | |||
1104 | PRInt32 numEvents = 0; | |||
1105 | PKIX_Int32 bytesRead = 0; | |||
1106 | PKIX_Int32 bytesWritten = 0; | |||
1107 | PRErrorCode errorcode = 0; | |||
1108 | ||||
1109 | PKIX_ENTER(SOCKET, "pkix_pl_Socket_Poll")static const char cMyFuncName[] = {"pkix_pl_Socket_Poll"}; PKIX_StdVars stdVars = zeroStdVars; stdVars.aMyFuncName = cMyFuncName; stdVars .aPkixType = PKIX_SOCKET_ERROR; ; do { if (pkixLoggersDebugTrace ) { pkix_Logger_Check(pkixLoggersDebugTrace, stdVars.aMyFuncName , ">>>", stdVars.aPkixType, 5, plContext); } } while (0);; | |||
| ||||
1110 | PKIX_NULLCHECK_ONE(sock)do { if ((sock) == ((void*)0)){ stdVars.aPkixErrorReceived = ( (PKIX_Boolean) 1); stdVars.aPkixErrorCode = PKIX_NULLARGUMENT ; return PKIX_DoReturn(&stdVars, (PKIX_FATAL_ERROR), ((PKIX_Boolean ) 1), plContext);; } } while (0); | |||
1111 | ||||
1112 | pollDesc.fd = sock->clientSock; | |||
1113 | pollDesc.in_flags = 0; | |||
1114 | pollDesc.out_flags = 0; | |||
1115 | ||||
1116 | if ((pBytesWritten) && | |||
1117 | ((sock->status == SOCKET_SENDPENDING) || | |||
1118 | (sock->status == SOCKET_SENDRCVPENDING))) { | |||
1119 | pollDesc.in_flags = PR_POLL_WRITE0x2; | |||
1120 | } | |||
1121 | ||||
1122 | if ((pBytesRead) && | |||
1123 | ((sock->status == SOCKET_RCVPENDING) || | |||
1124 | (sock->status == SOCKET_SENDRCVPENDING))) { | |||
1125 | pollDesc.in_flags |= PR_POLL_READ0x1; | |||
1126 | } | |||
1127 | ||||
1128 | PKIX_PL_NSSCALLRV(SOCKET, numEvents, PR_Poll, (&pollDesc, 1, 0)); numEvents = (PR_Poll (&pollDesc, 1, 0)); | |||
1129 | ||||
1130 | if (numEvents < 0) { | |||
1131 | PKIX_ERROR(PKIX_PRPOLLFAILED){ { if (pkixLoggersErrors) { pkix_Logger_CheckWithCode(pkixLoggersErrors , PKIX_PRPOLLFAILED, ((void*)0), stdVars.aPkixType, 2, plContext ); } } stdVars.aPkixErrorReceived = ((PKIX_Boolean) 1); stdVars .aPkixErrorCode = PKIX_PRPOLLFAILED; goto cleanup; }; | |||
1132 | } else if (numEvents > 0) { | |||
1133 | if (pollDesc.out_flags & PR_POLL_WRITE0x2) { | |||
1134 | PKIX_CHECK(pkix_pl_Socket_Senddo { stdVars.aPkixErrorResult = (pkix_pl_Socket_Send (sock, sock ->writeBuf, sock->writeBufSize, &bytesWritten, plContext )); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode = PKIX_SOCKETSENDFAILED; goto cleanup; } } while (0) | |||
1135 | (sock,do { stdVars.aPkixErrorResult = (pkix_pl_Socket_Send (sock, sock ->writeBuf, sock->writeBufSize, &bytesWritten, plContext )); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode = PKIX_SOCKETSENDFAILED; goto cleanup; } } while (0) | |||
1136 | sock->writeBuf,do { stdVars.aPkixErrorResult = (pkix_pl_Socket_Send (sock, sock ->writeBuf, sock->writeBufSize, &bytesWritten, plContext )); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode = PKIX_SOCKETSENDFAILED; goto cleanup; } } while (0) | |||
1137 | sock->writeBufSize,do { stdVars.aPkixErrorResult = (pkix_pl_Socket_Send (sock, sock ->writeBuf, sock->writeBufSize, &bytesWritten, plContext )); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode = PKIX_SOCKETSENDFAILED; goto cleanup; } } while (0) | |||
1138 | &bytesWritten,do { stdVars.aPkixErrorResult = (pkix_pl_Socket_Send (sock, sock ->writeBuf, sock->writeBufSize, &bytesWritten, plContext )); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode = PKIX_SOCKETSENDFAILED; goto cleanup; } } while (0) | |||
1139 | plContext),do { stdVars.aPkixErrorResult = (pkix_pl_Socket_Send (sock, sock ->writeBuf, sock->writeBufSize, &bytesWritten, plContext )); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode = PKIX_SOCKETSENDFAILED; goto cleanup; } } while (0) | |||
1140 | PKIX_SOCKETSENDFAILED)do { stdVars.aPkixErrorResult = (pkix_pl_Socket_Send (sock, sock ->writeBuf, sock->writeBufSize, &bytesWritten, plContext )); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode = PKIX_SOCKETSENDFAILED; goto cleanup; } } while (0); | |||
1141 | *pBytesWritten = (PKIX_Int32)bytesWritten; | |||
1142 | if (bytesWritten >= 0) { | |||
1143 | sock->writeBuf = NULL((void*)0); | |||
1144 | sock->writeBufSize = 0; | |||
1145 | } | |||
1146 | } | |||
1147 | ||||
1148 | if (pollDesc.out_flags & PR_POLL_READ0x1) { | |||
1149 | PKIX_CHECK(pkix_pl_Socket_Recvdo { stdVars.aPkixErrorResult = (pkix_pl_Socket_Recv (sock, sock ->readBuf, sock->readBufSize, &bytesRead, plContext )); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode = PKIX_SOCKETRECVFAILED; goto cleanup; } } while (0) | |||
1150 | (sock,do { stdVars.aPkixErrorResult = (pkix_pl_Socket_Recv (sock, sock ->readBuf, sock->readBufSize, &bytesRead, plContext )); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode = PKIX_SOCKETRECVFAILED; goto cleanup; } } while (0) | |||
1151 | sock->readBuf,do { stdVars.aPkixErrorResult = (pkix_pl_Socket_Recv (sock, sock ->readBuf, sock->readBufSize, &bytesRead, plContext )); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode = PKIX_SOCKETRECVFAILED; goto cleanup; } } while (0) | |||
1152 | sock->readBufSize,do { stdVars.aPkixErrorResult = (pkix_pl_Socket_Recv (sock, sock ->readBuf, sock->readBufSize, &bytesRead, plContext )); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode = PKIX_SOCKETRECVFAILED; goto cleanup; } } while (0) | |||
1153 | &bytesRead,do { stdVars.aPkixErrorResult = (pkix_pl_Socket_Recv (sock, sock ->readBuf, sock->readBufSize, &bytesRead, plContext )); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode = PKIX_SOCKETRECVFAILED; goto cleanup; } } while (0) | |||
1154 | plContext),do { stdVars.aPkixErrorResult = (pkix_pl_Socket_Recv (sock, sock ->readBuf, sock->readBufSize, &bytesRead, plContext )); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode = PKIX_SOCKETRECVFAILED; goto cleanup; } } while (0) | |||
1155 | PKIX_SOCKETRECVFAILED)do { stdVars.aPkixErrorResult = (pkix_pl_Socket_Recv (sock, sock ->readBuf, sock->readBufSize, &bytesRead, plContext )); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode = PKIX_SOCKETRECVFAILED; goto cleanup; } } while (0); | |||
1156 | *pBytesRead = (PKIX_Int32)bytesRead; | |||
| ||||
1157 | if (bytesRead >= 0) { | |||
1158 | sock->readBuf = NULL((void*)0); | |||
1159 | sock->readBufSize = 0; | |||
1160 | } | |||
1161 | } | |||
1162 | } else if (numEvents == 0) { | |||
1163 | errorcode = PR_GetError(); | |||
1164 | if (errorcode != PR_WOULD_BLOCK_ERROR(-5998L)) { | |||
1165 | #ifdef PKIX_SOCKETDEBUG | |||
1166 | printf | |||
1167 | ("pkix_pl_Socket_Poll: %s\n", | |||
1168 | PR_ErrorToString(errorcode, PR_LANGUAGE_EN1)); | |||
1169 | #endif | |||
1170 | PKIX_ERROR(PKIX_PRPOLLFAILED){ { if (pkixLoggersErrors) { pkix_Logger_CheckWithCode(pkixLoggersErrors , PKIX_PRPOLLFAILED, ((void*)0), stdVars.aPkixType, 2, plContext ); } } stdVars.aPkixErrorReceived = ((PKIX_Boolean) 1); stdVars .aPkixErrorCode = PKIX_PRPOLLFAILED; goto cleanup; }; | |||
1171 | } | |||
1172 | if (pBytesWritten) { | |||
1173 | *pBytesWritten = 0; | |||
1174 | } | |||
1175 | if (pBytesRead) { | |||
1176 | *pBytesRead = 0; | |||
1177 | } | |||
1178 | } | |||
1179 | ||||
1180 | cleanup: | |||
1181 | ||||
1182 | PKIX_RETURN(SOCKET)return PKIX_DoReturn(&stdVars, (PKIX_SOCKET_ERROR), ((PKIX_Boolean ) 1), plContext);; | |||
1183 | } | |||
1184 | ||||
1185 | /* | |||
1186 | * FUNCTION: pkix_pl_Socket_Accept | |||
1187 | * DESCRIPTION: | |||
1188 | * | |||
1189 | * This functions accepts a client connection for the server Socket pointed | |||
1190 | * to by "serverSocket", creating a new Socket and storing the result at | |||
1191 | * "pRendezvousSocket". If "serverSocket" is in non-blocking mode, this | |||
1192 | * function will return NULL if there is no client connection to accept. | |||
1193 | * Otherwise this function will block until a connection is available. | |||
1194 | * When a client connection is available the new Socket will have the same | |||
1195 | * blocking/non-blocking property as "serverSocket". | |||
1196 | * | |||
1197 | * PARAMETERS: | |||
1198 | * "serverSocket" | |||
1199 | * The address of the Socket for which a client connection is to be | |||
1200 | * accepted. Must be non-NULL. | |||
1201 | * "pRendezvousSocket" | |||
1202 | * The address at which the created Socket is stored, when a client | |||
1203 | * connection is available, or at which NULL is stored, if no connection | |||
1204 | * is available for a non-blocking "serverSocket". Must be non-NULL. | |||
1205 | * "plContext" | |||
1206 | * Platform-specific context pointer | |||
1207 | * THREAD SAFETY: | |||
1208 | * Thread Safe (see Thread Safety definitions in Programmer's Guide) | |||
1209 | * RETURNS: | |||
1210 | * none | |||
1211 | */ | |||
1212 | static PKIX_Error * | |||
1213 | pkix_pl_Socket_Accept( | |||
1214 | PKIX_PL_Socket *serverSocket, | |||
1215 | PKIX_PL_Socket **pRendezvousSocket, | |||
1216 | void *plContext) | |||
1217 | { | |||
1218 | PRErrorCode errorcode = 0; | |||
1219 | PRFileDesc *rendezvousSock = NULL((void*)0); | |||
1220 | PRNetAddr *clientAddr = NULL((void*)0); | |||
1221 | PKIX_PL_Socket *newSocket = NULL((void*)0); | |||
1222 | ||||
1223 | PKIX_ENTER(SOCKET, "pkix_pl_Socket_Accept")static const char cMyFuncName[] = {"pkix_pl_Socket_Accept"}; PKIX_StdVars stdVars = zeroStdVars; stdVars.aMyFuncName = cMyFuncName; stdVars .aPkixType = PKIX_SOCKET_ERROR; ; do { if (pkixLoggersDebugTrace ) { pkix_Logger_Check(pkixLoggersDebugTrace, stdVars.aMyFuncName , ">>>", stdVars.aPkixType, 5, plContext); } } while (0);; | |||
1224 | PKIX_NULLCHECK_TWO(serverSocket, pRendezvousSocket)do { if (((serverSocket) == ((void*)0)) || ((pRendezvousSocket ) == ((void*)0))){ stdVars.aPkixErrorReceived = ((PKIX_Boolean ) 1); stdVars.aPkixErrorCode = PKIX_NULLARGUMENT; return PKIX_DoReturn (&stdVars, (PKIX_FATAL_ERROR), ((PKIX_Boolean) 1), plContext );; } } while (0); | |||
1225 | ||||
1226 | PKIX_PL_NSSCALLRV(SOCKET, rendezvousSock, PR_Accept,; rendezvousSock = (PR_Accept (serverSocket->serverSock, clientAddr , serverSocket->timeout)) | |||
1227 | (serverSocket->serverSock, clientAddr, serverSocket->timeout)); rendezvousSock = (PR_Accept (serverSocket->serverSock, clientAddr , serverSocket->timeout)); | |||
1228 | ||||
1229 | if (!rendezvousSock) { | |||
1230 | errorcode = PR_GetError(); | |||
1231 | if (errorcode != PR_WOULD_BLOCK_ERROR(-5998L)) { | |||
1232 | #ifdef PKIX_SOCKETDEBUG | |||
1233 | printf | |||
1234 | ("pkix_pl_Socket_Accept: %s\n", | |||
1235 | PR_ErrorToString(errorcode, PR_LANGUAGE_EN1)); | |||
1236 | #endif | |||
1237 | PKIX_ERROR(PKIX_PRACCEPTFAILED){ { if (pkixLoggersErrors) { pkix_Logger_CheckWithCode(pkixLoggersErrors , PKIX_PRACCEPTFAILED, ((void*)0), stdVars.aPkixType, 2, plContext ); } } stdVars.aPkixErrorReceived = ((PKIX_Boolean) 1); stdVars .aPkixErrorCode = PKIX_PRACCEPTFAILED; goto cleanup; }; | |||
1238 | } | |||
1239 | serverSocket->status = SOCKET_ACCEPTPENDING; | |||
1240 | *pRendezvousSocket = NULL((void*)0); | |||
1241 | goto cleanup; | |||
1242 | ||||
1243 | } | |||
1244 | ||||
1245 | #ifdef PKIX_SOCKETDEBUG | |||
1246 | printf("Successful accept!\n"); | |||
1247 | #endif | |||
1248 | ||||
1249 | PKIX_CHECK(PKIX_PL_Object_Allocdo { stdVars.aPkixErrorResult = (PKIX_PL_Object_Alloc (PKIX_SOCKET_TYPE , sizeof (PKIX_PL_Socket), (PKIX_PL_Object **)&newSocket, plContext)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode = PKIX_COULDNOTCREATESOCKETOBJECT; goto cleanup; } } while ( 0) | |||
1250 | (PKIX_SOCKET_TYPE,do { stdVars.aPkixErrorResult = (PKIX_PL_Object_Alloc (PKIX_SOCKET_TYPE , sizeof (PKIX_PL_Socket), (PKIX_PL_Object **)&newSocket, plContext)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode = PKIX_COULDNOTCREATESOCKETOBJECT; goto cleanup; } } while ( 0) | |||
1251 | sizeof (PKIX_PL_Socket),do { stdVars.aPkixErrorResult = (PKIX_PL_Object_Alloc (PKIX_SOCKET_TYPE , sizeof (PKIX_PL_Socket), (PKIX_PL_Object **)&newSocket, plContext)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode = PKIX_COULDNOTCREATESOCKETOBJECT; goto cleanup; } } while ( 0) | |||
1252 | (PKIX_PL_Object **)&newSocket,do { stdVars.aPkixErrorResult = (PKIX_PL_Object_Alloc (PKIX_SOCKET_TYPE , sizeof (PKIX_PL_Socket), (PKIX_PL_Object **)&newSocket, plContext)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode = PKIX_COULDNOTCREATESOCKETOBJECT; goto cleanup; } } while ( 0) | |||
1253 | plContext),do { stdVars.aPkixErrorResult = (PKIX_PL_Object_Alloc (PKIX_SOCKET_TYPE , sizeof (PKIX_PL_Socket), (PKIX_PL_Object **)&newSocket, plContext)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode = PKIX_COULDNOTCREATESOCKETOBJECT; goto cleanup; } } while ( 0) | |||
1254 | PKIX_COULDNOTCREATESOCKETOBJECT)do { stdVars.aPkixErrorResult = (PKIX_PL_Object_Alloc (PKIX_SOCKET_TYPE , sizeof (PKIX_PL_Socket), (PKIX_PL_Object **)&newSocket, plContext)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode = PKIX_COULDNOTCREATESOCKETOBJECT; goto cleanup; } } while ( 0); | |||
1255 | ||||
1256 | newSocket->isServer = PKIX_FALSE((PKIX_Boolean) 0); | |||
1257 | newSocket->timeout = serverSocket->timeout; | |||
1258 | newSocket->clientSock = rendezvousSock; | |||
1259 | newSocket->serverSock = NULL((void*)0); | |||
1260 | newSocket->netAddr = NULL((void*)0); | |||
1261 | newSocket->status = SOCKET_CONNECTED; | |||
1262 | newSocket->callbackList.shutdownCallback = pkix_pl_Socket_Shutdown; | |||
1263 | newSocket->callbackList.listenCallback = pkix_pl_Socket_Listen; | |||
1264 | newSocket->callbackList.acceptCallback = pkix_pl_Socket_Accept; | |||
1265 | newSocket->callbackList.connectcontinueCallback = | |||
1266 | pkix_pl_Socket_ConnectContinue; | |||
1267 | newSocket->callbackList.sendCallback = pkix_pl_Socket_Send; | |||
1268 | newSocket->callbackList.recvCallback = pkix_pl_Socket_Recv; | |||
1269 | newSocket->callbackList.pollCallback = pkix_pl_Socket_Poll; | |||
1270 | ||||
1271 | if (serverSocket->timeout == 0) { | |||
1272 | PKIX_CHECK(pkix_pl_Socket_SetNonBlockingdo { stdVars.aPkixErrorResult = (pkix_pl_Socket_SetNonBlocking (rendezvousSock, plContext)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass ; stdVars.aPkixErrorCode = PKIX_SOCKETSETNONBLOCKINGFAILED; goto cleanup; } } while (0) | |||
1273 | (rendezvousSock, plContext),do { stdVars.aPkixErrorResult = (pkix_pl_Socket_SetNonBlocking (rendezvousSock, plContext)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass ; stdVars.aPkixErrorCode = PKIX_SOCKETSETNONBLOCKINGFAILED; goto cleanup; } } while (0) | |||
1274 | PKIX_SOCKETSETNONBLOCKINGFAILED)do { stdVars.aPkixErrorResult = (pkix_pl_Socket_SetNonBlocking (rendezvousSock, plContext)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass ; stdVars.aPkixErrorCode = PKIX_SOCKETSETNONBLOCKINGFAILED; goto cleanup; } } while (0); | |||
1275 | } | |||
1276 | ||||
1277 | *pRendezvousSocket = newSocket; | |||
1278 | ||||
1279 | cleanup: | |||
1280 | ||||
1281 | PKIX_RETURN(SOCKET)return PKIX_DoReturn(&stdVars, (PKIX_SOCKET_ERROR), ((PKIX_Boolean ) 1), plContext);; | |||
1282 | } | |||
1283 | ||||
1284 | /* | |||
1285 | * FUNCTION: pkix_pl_Socket_Create | |||
1286 | * DESCRIPTION: | |||
1287 | * | |||
1288 | * This function creates a new Socket, setting it to be a server or a client | |||
1289 | * according to the value of "isServer", setting its timeout value from | |||
1290 | * "timeout" and server address from "netAddr", and stores the created Socket | |||
1291 | * at "pSocket". | |||
1292 | * | |||
1293 | * PARAMETERS: | |||
1294 | * "isServer" | |||
1295 | * The Boolean value indicating if PKIX_TRUE, that a server socket (using | |||
1296 | * Bind, Listen, and Accept) is to be created, or if PKIX_FALSE, that a | |||
1297 | * client socket (using Connect) is to be created. | |||
1298 | * "timeout" | |||
1299 | * A PRTimeInterval value to be used for I/O waits for this socket. If | |||
1300 | * zero, non-blocking I/O is to be used. | |||
1301 | * "netAddr" | |||
1302 | * The PRNetAddr to be used for the Bind function, if this is a server | |||
1303 | * socket, or for the Connect, if this is a client socket. | |||
1304 | * "pSocket" | |||
1305 | * The address at which the Socket is to be stored. Must be non-NULL. | |||
1306 | * "plContext" | |||
1307 | * Platform-specific context pointer. | |||
1308 | * THREAD SAFETY: | |||
1309 | * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |||
1310 | * RETURNS: | |||
1311 | * Returns NULL if the function succeeds. | |||
1312 | * Returns a Socket Error if the function fails in | |||
1313 | * a non-fatal way. | |||
1314 | * Returns a Fatal Error if the function fails in an unrecoverable way. | |||
1315 | */ | |||
1316 | PKIX_Error * | |||
1317 | pkix_pl_Socket_Create( | |||
1318 | PKIX_Boolean isServer, | |||
1319 | PRIntervalTime timeout, | |||
1320 | PRNetAddr *netAddr, | |||
1321 | PRErrorCode *status, | |||
1322 | PKIX_PL_Socket **pSocket, | |||
1323 | void *plContext) | |||
1324 | { | |||
1325 | PKIX_PL_Socket *socket = NULL((void*)0); | |||
1326 | ||||
1327 | PKIX_ENTER(SOCKET, "pkix_pl_Socket_Create")static const char cMyFuncName[] = {"pkix_pl_Socket_Create"}; PKIX_StdVars stdVars = zeroStdVars; stdVars.aMyFuncName = cMyFuncName; stdVars .aPkixType = PKIX_SOCKET_ERROR; ; do { if (pkixLoggersDebugTrace ) { pkix_Logger_Check(pkixLoggersDebugTrace, stdVars.aMyFuncName , ">>>", stdVars.aPkixType, 5, plContext); } } while (0);; | |||
1328 | PKIX_NULLCHECK_ONE(pSocket)do { if ((pSocket) == ((void*)0)){ stdVars.aPkixErrorReceived = ((PKIX_Boolean) 1); stdVars.aPkixErrorCode = PKIX_NULLARGUMENT ; return PKIX_DoReturn(&stdVars, (PKIX_FATAL_ERROR), ((PKIX_Boolean ) 1), plContext);; } } while (0); | |||
1329 | ||||
1330 | PKIX_CHECK(PKIX_PL_Object_Allocdo { stdVars.aPkixErrorResult = (PKIX_PL_Object_Alloc (PKIX_SOCKET_TYPE , sizeof (PKIX_PL_Socket), (PKIX_PL_Object **)&socket, plContext )); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode = PKIX_COULDNOTCREATESOCKETOBJECT; goto cleanup; } } while ( 0) | |||
1331 | (PKIX_SOCKET_TYPE,do { stdVars.aPkixErrorResult = (PKIX_PL_Object_Alloc (PKIX_SOCKET_TYPE , sizeof (PKIX_PL_Socket), (PKIX_PL_Object **)&socket, plContext )); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode = PKIX_COULDNOTCREATESOCKETOBJECT; goto cleanup; } } while ( 0) | |||
1332 | sizeof (PKIX_PL_Socket),do { stdVars.aPkixErrorResult = (PKIX_PL_Object_Alloc (PKIX_SOCKET_TYPE , sizeof (PKIX_PL_Socket), (PKIX_PL_Object **)&socket, plContext )); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode = PKIX_COULDNOTCREATESOCKETOBJECT; goto cleanup; } } while ( 0) | |||
1333 | (PKIX_PL_Object **)&socket,do { stdVars.aPkixErrorResult = (PKIX_PL_Object_Alloc (PKIX_SOCKET_TYPE , sizeof (PKIX_PL_Socket), (PKIX_PL_Object **)&socket, plContext )); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode = PKIX_COULDNOTCREATESOCKETOBJECT; goto cleanup; } } while ( 0) | |||
1334 | plContext),do { stdVars.aPkixErrorResult = (PKIX_PL_Object_Alloc (PKIX_SOCKET_TYPE , sizeof (PKIX_PL_Socket), (PKIX_PL_Object **)&socket, plContext )); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode = PKIX_COULDNOTCREATESOCKETOBJECT; goto cleanup; } } while ( 0) | |||
1335 | PKIX_COULDNOTCREATESOCKETOBJECT)do { stdVars.aPkixErrorResult = (PKIX_PL_Object_Alloc (PKIX_SOCKET_TYPE , sizeof (PKIX_PL_Socket), (PKIX_PL_Object **)&socket, plContext )); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode = PKIX_COULDNOTCREATESOCKETOBJECT; goto cleanup; } } while ( 0); | |||
1336 | ||||
1337 | socket->isServer = isServer; | |||
1338 | socket->timeout = timeout; | |||
1339 | socket->clientSock = NULL((void*)0); | |||
1340 | socket->serverSock = NULL((void*)0); | |||
1341 | socket->netAddr = netAddr; | |||
1342 | ||||
1343 | socket->callbackList.listenCallback = pkix_pl_Socket_Listen; | |||
1344 | socket->callbackList.acceptCallback = pkix_pl_Socket_Accept; | |||
1345 | socket->callbackList.connectcontinueCallback = | |||
1346 | pkix_pl_Socket_ConnectContinue; | |||
1347 | socket->callbackList.sendCallback = pkix_pl_Socket_Send; | |||
1348 | socket->callbackList.recvCallback = pkix_pl_Socket_Recv; | |||
1349 | socket->callbackList.pollCallback = pkix_pl_Socket_Poll; | |||
1350 | socket->callbackList.shutdownCallback = pkix_pl_Socket_Shutdown; | |||
1351 | ||||
1352 | if (isServer) { | |||
1353 | PKIX_CHECK(pkix_pl_Socket_CreateServer(socket, plContext),do { stdVars.aPkixErrorResult = (pkix_pl_Socket_CreateServer( socket, plContext)); if (stdVars.aPkixErrorResult) { stdVars. aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars .aPkixErrorCode = PKIX_SOCKETCREATESERVERFAILED; goto cleanup ; } } while (0) | |||
1354 | PKIX_SOCKETCREATESERVERFAILED)do { stdVars.aPkixErrorResult = (pkix_pl_Socket_CreateServer( socket, plContext)); if (stdVars.aPkixErrorResult) { stdVars. aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars .aPkixErrorCode = PKIX_SOCKETCREATESERVERFAILED; goto cleanup ; } } while (0); | |||
1355 | *status = 0; | |||
1356 | } else { | |||
1357 | socket->timeout = timeout; | |||
1358 | PKIX_CHECK(pkix_pl_Socket_CreateClient(socket, plContext),do { stdVars.aPkixErrorResult = (pkix_pl_Socket_CreateClient( socket, plContext)); if (stdVars.aPkixErrorResult) { stdVars. aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars .aPkixErrorCode = PKIX_SOCKETCREATECLIENTFAILED; goto cleanup ; } } while (0) | |||
1359 | PKIX_SOCKETCREATECLIENTFAILED)do { stdVars.aPkixErrorResult = (pkix_pl_Socket_CreateClient( socket, plContext)); if (stdVars.aPkixErrorResult) { stdVars. aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars .aPkixErrorCode = PKIX_SOCKETCREATECLIENTFAILED; goto cleanup ; } } while (0); | |||
1360 | PKIX_CHECK(pkix_pl_Socket_Connect(socket, status, plContext),do { stdVars.aPkixErrorResult = (pkix_pl_Socket_Connect(socket , status, plContext)); if (stdVars.aPkixErrorResult) { stdVars .aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars .aPkixErrorCode = PKIX_SOCKETCONNECTFAILED; goto cleanup; } } while (0) | |||
1361 | PKIX_SOCKETCONNECTFAILED)do { stdVars.aPkixErrorResult = (pkix_pl_Socket_Connect(socket , status, plContext)); if (stdVars.aPkixErrorResult) { stdVars .aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars .aPkixErrorCode = PKIX_SOCKETCONNECTFAILED; goto cleanup; } } while (0); | |||
1362 | } | |||
1363 | ||||
1364 | *pSocket = socket; | |||
1365 | ||||
1366 | cleanup: | |||
1367 | if (PKIX_ERROR_RECEIVED(stdVars.aPkixErrorReceived || stdVars.aPkixErrorResult || stdVars .aPkixTempErrorReceived || stdVars.aPkixErrorList)) { | |||
1368 | PKIX_DECREF(socket)do { if (socket){ stdVars.aPkixTempResult = PKIX_PL_Object_DecRef ((PKIX_PL_Object *)(socket), plContext); if (stdVars.aPkixTempResult ) { PKIX_DoAddError(&stdVars, stdVars.aPkixTempResult, plContext ); stdVars.aPkixTempResult = ((void*)0); } socket = ((void*)0 ); } } while (0); | |||
1369 | } | |||
1370 | ||||
1371 | PKIX_RETURN(SOCKET)return PKIX_DoReturn(&stdVars, (PKIX_SOCKET_ERROR), ((PKIX_Boolean ) 1), plContext);; | |||
1372 | } | |||
1373 | ||||
1374 | /* | |||
1375 | * FUNCTION: pkix_pl_Socket_CreateByName | |||
1376 | * DESCRIPTION: | |||
1377 | * | |||
1378 | * This function creates a new Socket, setting it to be a server or a client | |||
1379 | * according to the value of "isServer", setting its timeout value from | |||
1380 | * "timeout" and server address and port number from "serverName", and stores | |||
1381 | * the status at "pStatus" and the created Socket at "pSocket". | |||
1382 | * | |||
1383 | * If isServer is PKIX_TRUE, it is attempted to create the socket with an ip | |||
1384 | * address of PR_INADDR_ANY. | |||
1385 | * | |||
1386 | * PARAMETERS: | |||
1387 | * "isServer" | |||
1388 | * The Boolean value indicating if PKIX_TRUE, that a server socket (using | |||
1389 | * Bind, Listen, and Accept) is to be created, or if PKIX_FALSE, that a | |||
1390 | * client socket (using Connect) is to be created. | |||
1391 | * "timeout" | |||
1392 | * A PRTimeInterval value to be used for I/O waits for this socket. If | |||
1393 | * zero, non-blocking I/O is to be used. | |||
1394 | * "serverName" | |||
1395 | * Address of a character string consisting of the server's domain name | |||
1396 | * followed by a colon and a port number for the desired socket. | |||
1397 | * "pStatus" | |||
1398 | * Address at which the PRErrorCode resulting from the create is | |||
1399 | * stored. Must be non-NULL. | |||
1400 | * "pSocket" | |||
1401 | * The address at which the Socket is to be stored. Must be non-NULL. | |||
1402 | * "plContext" | |||
1403 | * Platform-specific context pointer. | |||
1404 | * THREAD SAFETY: | |||
1405 | * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |||
1406 | * RETURNS: | |||
1407 | * Returns NULL if the function succeeds. | |||
1408 | * Returns a Socket Error if the function fails in | |||
1409 | * a non-fatal way. | |||
1410 | * Returns a Fatal Error if the function fails in an unrecoverable way. | |||
1411 | */ | |||
1412 | PKIX_Error * | |||
1413 | pkix_pl_Socket_CreateByName( | |||
1414 | PKIX_Boolean isServer, | |||
1415 | PRIntervalTime timeout, | |||
1416 | char *serverName, | |||
1417 | PRErrorCode *pStatus, | |||
1418 | PKIX_PL_Socket **pSocket, | |||
1419 | void *plContext) | |||
1420 | { | |||
1421 | PRNetAddr netAddr; | |||
1422 | PKIX_PL_Socket *socket = NULL((void*)0); | |||
1423 | char *sepPtr = NULL((void*)0); | |||
1424 | PRHostEnt hostent; | |||
1425 | PRIntn hostenum; | |||
1426 | PRStatus prstatus = PR_FAILURE; | |||
1427 | char buf[PR_NETDB_BUF_SIZE2048]; | |||
1428 | PRUint16 portNum = 0; | |||
1429 | char *localCopyName = NULL((void*)0); | |||
1430 | ||||
1431 | PKIX_ENTER(SOCKET, "pkix_pl_Socket_CreateByName")static const char cMyFuncName[] = {"pkix_pl_Socket_CreateByName" }; PKIX_StdVars stdVars = zeroStdVars; stdVars.aMyFuncName = cMyFuncName ; stdVars.aPkixType = PKIX_SOCKET_ERROR; ; do { if (pkixLoggersDebugTrace ) { pkix_Logger_Check(pkixLoggersDebugTrace, stdVars.aMyFuncName , ">>>", stdVars.aPkixType, 5, plContext); } } while (0);; | |||
1432 | PKIX_NULLCHECK_TWO(serverName, pSocket)do { if (((serverName) == ((void*)0)) || ((pSocket) == ((void *)0))){ stdVars.aPkixErrorReceived = ((PKIX_Boolean) 1); stdVars .aPkixErrorCode = PKIX_NULLARGUMENT; return PKIX_DoReturn(& stdVars, (PKIX_FATAL_ERROR), ((PKIX_Boolean) 1), plContext);; } } while (0); | |||
1433 | ||||
1434 | localCopyName = PL_strdup(serverName); | |||
1435 | ||||
1436 | sepPtr = strchr(localCopyName, ':'); | |||
1437 | /* First strip off the portnum, if present, from the end of the name */ | |||
1438 | if (sepPtr) { | |||
1439 | *sepPtr++ = '\0'; | |||
1440 | portNum = (PRUint16)atoi(sepPtr); | |||
1441 | } else { | |||
1442 | portNum = (PRUint16)LDAP_PORT389; | |||
1443 | } | |||
1444 | ||||
1445 | prstatus = PR_GetHostByName(localCopyName, buf, sizeof(buf), &hostent); | |||
1446 | ||||
1447 | if ((prstatus != PR_SUCCESS) || (hostent.h_length != 4)) { | |||
1448 | /* | |||
1449 | * The hostname may be a fully-qualified name. Try using just | |||
1450 | * the leftmost component in our lookup. | |||
1451 | */ | |||
1452 | sepPtr = strchr(localCopyName, '.'); | |||
1453 | if (sepPtr) { | |||
1454 | *sepPtr++ = '\0'; | |||
1455 | } | |||
1456 | prstatus = PR_GetHostByName | |||
1457 | (localCopyName, buf, sizeof(buf), &hostent); | |||
1458 | ||||
1459 | if ((prstatus != PR_SUCCESS) || (hostent.h_length != 4)) { | |||
1460 | PKIX_ERROR{ { if (pkixLoggersErrors) { pkix_Logger_CheckWithCode(pkixLoggersErrors , PKIX_PRGETHOSTBYNAMEREJECTSHOSTNAMEARGUMENT, ((void*)0), stdVars .aPkixType, 2, plContext); } } stdVars.aPkixErrorReceived = ( (PKIX_Boolean) 1); stdVars.aPkixErrorCode = PKIX_PRGETHOSTBYNAMEREJECTSHOSTNAMEARGUMENT ; goto cleanup; } | |||
1461 | (PKIX_PRGETHOSTBYNAMEREJECTSHOSTNAMEARGUMENT){ { if (pkixLoggersErrors) { pkix_Logger_CheckWithCode(pkixLoggersErrors , PKIX_PRGETHOSTBYNAMEREJECTSHOSTNAMEARGUMENT, ((void*)0), stdVars .aPkixType, 2, plContext); } } stdVars.aPkixErrorReceived = ( (PKIX_Boolean) 1); stdVars.aPkixErrorCode = PKIX_PRGETHOSTBYNAMEREJECTSHOSTNAMEARGUMENT ; goto cleanup; }; | |||
1462 | } | |||
1463 | } | |||
1464 | ||||
1465 | netAddr.inet.family = PR_AF_INET2; | |||
1466 | netAddr.inet.port = PR_htons(portNum); | |||
1467 | ||||
1468 | if (isServer) { | |||
1469 | ||||
1470 | netAddr.inet.ip = PR_htonl(PR_INADDR_ANY((in_addr_t) 0x00000000)); | |||
1471 | ||||
1472 | } else { | |||
1473 | ||||
1474 | hostenum = PR_EnumerateHostEnt(0, &hostent, portNum, &netAddr); | |||
1475 | if (hostenum == -1) { | |||
1476 | PKIX_ERROR(PKIX_PRENUMERATEHOSTENTFAILED){ { if (pkixLoggersErrors) { pkix_Logger_CheckWithCode(pkixLoggersErrors , PKIX_PRENUMERATEHOSTENTFAILED, ((void*)0), stdVars.aPkixType , 2, plContext); } } stdVars.aPkixErrorReceived = ((PKIX_Boolean ) 1); stdVars.aPkixErrorCode = PKIX_PRENUMERATEHOSTENTFAILED; goto cleanup; }; | |||
1477 | } | |||
1478 | } | |||
1479 | ||||
1480 | PKIX_CHECK(PKIX_PL_Object_Allocdo { stdVars.aPkixErrorResult = (PKIX_PL_Object_Alloc (PKIX_SOCKET_TYPE , sizeof (PKIX_PL_Socket), (PKIX_PL_Object **)&socket, plContext )); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode = PKIX_COULDNOTCREATESOCKETOBJECT; goto cleanup; } } while ( 0) | |||
1481 | (PKIX_SOCKET_TYPE,do { stdVars.aPkixErrorResult = (PKIX_PL_Object_Alloc (PKIX_SOCKET_TYPE , sizeof (PKIX_PL_Socket), (PKIX_PL_Object **)&socket, plContext )); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode = PKIX_COULDNOTCREATESOCKETOBJECT; goto cleanup; } } while ( 0) | |||
1482 | sizeof (PKIX_PL_Socket),do { stdVars.aPkixErrorResult = (PKIX_PL_Object_Alloc (PKIX_SOCKET_TYPE , sizeof (PKIX_PL_Socket), (PKIX_PL_Object **)&socket, plContext )); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode = PKIX_COULDNOTCREATESOCKETOBJECT; goto cleanup; } } while ( 0) | |||
1483 | (PKIX_PL_Object **)&socket,do { stdVars.aPkixErrorResult = (PKIX_PL_Object_Alloc (PKIX_SOCKET_TYPE , sizeof (PKIX_PL_Socket), (PKIX_PL_Object **)&socket, plContext )); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode = PKIX_COULDNOTCREATESOCKETOBJECT; goto cleanup; } } while ( 0) | |||
1484 | plContext),do { stdVars.aPkixErrorResult = (PKIX_PL_Object_Alloc (PKIX_SOCKET_TYPE , sizeof (PKIX_PL_Socket), (PKIX_PL_Object **)&socket, plContext )); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode = PKIX_COULDNOTCREATESOCKETOBJECT; goto cleanup; } } while ( 0) | |||
1485 | PKIX_COULDNOTCREATESOCKETOBJECT)do { stdVars.aPkixErrorResult = (PKIX_PL_Object_Alloc (PKIX_SOCKET_TYPE , sizeof (PKIX_PL_Socket), (PKIX_PL_Object **)&socket, plContext )); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode = PKIX_COULDNOTCREATESOCKETOBJECT; goto cleanup; } } while ( 0); | |||
1486 | ||||
1487 | socket->isServer = isServer; | |||
1488 | socket->timeout = timeout; | |||
1489 | socket->clientSock = NULL((void*)0); | |||
1490 | socket->serverSock = NULL((void*)0); | |||
1491 | socket->netAddr = &netAddr; | |||
1492 | ||||
1493 | socket->callbackList.listenCallback = pkix_pl_Socket_Listen; | |||
1494 | socket->callbackList.acceptCallback = pkix_pl_Socket_Accept; | |||
1495 | socket->callbackList.connectcontinueCallback = | |||
1496 | pkix_pl_Socket_ConnectContinue; | |||
1497 | socket->callbackList.sendCallback = pkix_pl_Socket_Send; | |||
1498 | socket->callbackList.recvCallback = pkix_pl_Socket_Recv; | |||
1499 | socket->callbackList.pollCallback = pkix_pl_Socket_Poll; | |||
1500 | socket->callbackList.shutdownCallback = pkix_pl_Socket_Shutdown; | |||
1501 | ||||
1502 | if (isServer) { | |||
1503 | PKIX_CHECK(pkix_pl_Socket_CreateServer(socket, plContext),do { stdVars.aPkixErrorResult = (pkix_pl_Socket_CreateServer( socket, plContext)); if (stdVars.aPkixErrorResult) { stdVars. aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars .aPkixErrorCode = PKIX_SOCKETCREATESERVERFAILED; goto cleanup ; } } while (0) | |||
1504 | PKIX_SOCKETCREATESERVERFAILED)do { stdVars.aPkixErrorResult = (pkix_pl_Socket_CreateServer( socket, plContext)); if (stdVars.aPkixErrorResult) { stdVars. aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars .aPkixErrorCode = PKIX_SOCKETCREATESERVERFAILED; goto cleanup ; } } while (0); | |||
1505 | *pStatus = 0; | |||
1506 | } else { | |||
1507 | PKIX_CHECK(pkix_pl_Socket_CreateClient(socket, plContext),do { stdVars.aPkixErrorResult = (pkix_pl_Socket_CreateClient( socket, plContext)); if (stdVars.aPkixErrorResult) { stdVars. aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars .aPkixErrorCode = PKIX_SOCKETCREATECLIENTFAILED; goto cleanup ; } } while (0) | |||
1508 | PKIX_SOCKETCREATECLIENTFAILED)do { stdVars.aPkixErrorResult = (pkix_pl_Socket_CreateClient( socket, plContext)); if (stdVars.aPkixErrorResult) { stdVars. aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars .aPkixErrorCode = PKIX_SOCKETCREATECLIENTFAILED; goto cleanup ; } } while (0); | |||
1509 | PKIX_CHECK(pkix_pl_Socket_Connect(socket, pStatus, plContext),do { stdVars.aPkixErrorResult = (pkix_pl_Socket_Connect(socket , pStatus, plContext)); if (stdVars.aPkixErrorResult) { stdVars .aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars .aPkixErrorCode = PKIX_SOCKETCONNECTFAILED; goto cleanup; } } while (0) | |||
1510 | PKIX_SOCKETCONNECTFAILED)do { stdVars.aPkixErrorResult = (pkix_pl_Socket_Connect(socket , pStatus, plContext)); if (stdVars.aPkixErrorResult) { stdVars .aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars .aPkixErrorCode = PKIX_SOCKETCONNECTFAILED; goto cleanup; } } while (0); | |||
1511 | } | |||
1512 | ||||
1513 | *pSocket = socket; | |||
1514 | ||||
1515 | cleanup: | |||
1516 | PL_strfree(localCopyName); | |||
1517 | ||||
1518 | if (PKIX_ERROR_RECEIVED(stdVars.aPkixErrorReceived || stdVars.aPkixErrorResult || stdVars .aPkixTempErrorReceived || stdVars.aPkixErrorList)) { | |||
1519 | PKIX_DECREF(socket)do { if (socket){ stdVars.aPkixTempResult = PKIX_PL_Object_DecRef ((PKIX_PL_Object *)(socket), plContext); if (stdVars.aPkixTempResult ) { PKIX_DoAddError(&stdVars, stdVars.aPkixTempResult, plContext ); stdVars.aPkixTempResult = ((void*)0); } socket = ((void*)0 ); } } while (0); | |||
1520 | } | |||
1521 | ||||
1522 | PKIX_RETURN(SOCKET)return PKIX_DoReturn(&stdVars, (PKIX_SOCKET_ERROR), ((PKIX_Boolean ) 1), plContext);; | |||
1523 | } | |||
1524 | ||||
1525 | /* | |||
1526 | * FUNCTION: pkix_pl_Socket_CreateByHostAndPort | |||
1527 | * DESCRIPTION: | |||
1528 | * | |||
1529 | * This function creates a new Socket, setting it to be a server or a client | |||
1530 | * according to the value of "isServer", setting its timeout value from | |||
1531 | * "timeout", host from "hostname", and port number from "portNum", and stores | |||
1532 | * the status at "pStatus" and the created Socket at "pSocket". | |||
1533 | * | |||
1534 | * If isServer is PKIX_TRUE, it is attempted to create the socket with an ip | |||
1535 | * address of PR_INADDR_ANY. | |||
1536 | * | |||
1537 | * PARAMETERS: | |||
1538 | * "isServer" | |||
1539 | * The Boolean value indicating if PKIX_TRUE, that a server socket (using | |||
1540 | * Bind, Listen, and Accept) is to be created, or if PKIX_FALSE, that a | |||
1541 | * client socket (using Connect) is to be created. | |||
1542 | * "timeout" | |||
1543 | * A PRTimeInterval value to be used for I/O waits for this socket. If | |||
1544 | * zero, non-blocking I/O is to be used. | |||
1545 | * "hostname" | |||
1546 | * Address of a character string consisting of the server's domain name. | |||
1547 | * "portNum" | |||
1548 | * UInt16 value of the port number for the desired socket. | |||
1549 | * "pStatus" | |||
1550 | * Address at which the PRErrorCode resulting from the create is | |||
1551 | * stored. Must be non-NULL. | |||
1552 | * "pSocket" | |||
1553 | * The address at which the Socket is to be stored. Must be non-NULL. | |||
1554 | * "plContext" | |||
1555 | * Platform-specific context pointer. | |||
1556 | * THREAD SAFETY: | |||
1557 | * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |||
1558 | * RETURNS: | |||
1559 | * Returns NULL if the function succeeds. | |||
1560 | * Returns a Socket Error if the function fails in | |||
1561 | * a non-fatal way. | |||
1562 | * Returns a Fatal Error if the function fails in an unrecoverable way. | |||
1563 | */ | |||
1564 | PKIX_Error * | |||
1565 | pkix_pl_Socket_CreateByHostAndPort( | |||
1566 | PKIX_Boolean isServer, | |||
1567 | PRIntervalTime timeout, | |||
1568 | char *hostname, | |||
1569 | PRUint16 portnum, | |||
1570 | PRErrorCode *pStatus, | |||
1571 | PKIX_PL_Socket **pSocket, | |||
1572 | void *plContext) | |||
1573 | { | |||
1574 | PRNetAddr netAddr; | |||
1575 | PKIX_PL_Socket *socket = NULL((void*)0); | |||
1576 | char *sepPtr = NULL((void*)0); | |||
1577 | PRHostEnt hostent; | |||
1578 | PRIntn hostenum; | |||
1579 | PRStatus prstatus = PR_FAILURE; | |||
1580 | char buf[PR_NETDB_BUF_SIZE2048]; | |||
1581 | ||||
1582 | PKIX_ENTER(SOCKET, "pkix_pl_Socket_CreateByHostAndPort")static const char cMyFuncName[] = {"pkix_pl_Socket_CreateByHostAndPort" }; PKIX_StdVars stdVars = zeroStdVars; stdVars.aMyFuncName = cMyFuncName ; stdVars.aPkixType = PKIX_SOCKET_ERROR; ; do { if (pkixLoggersDebugTrace ) { pkix_Logger_Check(pkixLoggersDebugTrace, stdVars.aMyFuncName , ">>>", stdVars.aPkixType, 5, plContext); } } while (0);; | |||
1583 | PKIX_NULLCHECK_THREE(hostname, pStatus, pSocket)do { if (((hostname) == ((void*)0)) || ((pStatus) == ((void*) 0)) || ((pSocket) == ((void*)0))){ stdVars.aPkixErrorReceived = ((PKIX_Boolean) 1); stdVars.aPkixErrorCode = PKIX_NULLARGUMENT ; return PKIX_DoReturn(&stdVars, (PKIX_FATAL_ERROR), ((PKIX_Boolean ) 1), plContext);; } } while (0); | |||
1584 | ||||
1585 | ||||
1586 | prstatus = PR_GetHostByName(hostname, buf, sizeof(buf), &hostent); | |||
1587 | ||||
1588 | if ((prstatus != PR_SUCCESS) || (hostent.h_length != 4)) { | |||
1589 | /* | |||
1590 | * The hostname may be a fully-qualified name. Try using just | |||
1591 | * the leftmost component in our lookup. | |||
1592 | */ | |||
1593 | sepPtr = strchr(hostname, '.'); | |||
1594 | if (sepPtr) { | |||
1595 | *sepPtr++ = '\0'; | |||
1596 | } | |||
1597 | prstatus = PR_GetHostByName(hostname, buf, sizeof(buf), &hostent); | |||
1598 | ||||
1599 | if ((prstatus != PR_SUCCESS) || (hostent.h_length != 4)) { | |||
1600 | PKIX_ERROR{ { if (pkixLoggersErrors) { pkix_Logger_CheckWithCode(pkixLoggersErrors , PKIX_PRGETHOSTBYNAMEREJECTSHOSTNAMEARGUMENT, ((void*)0), stdVars .aPkixType, 2, plContext); } } stdVars.aPkixErrorReceived = ( (PKIX_Boolean) 1); stdVars.aPkixErrorCode = PKIX_PRGETHOSTBYNAMEREJECTSHOSTNAMEARGUMENT ; goto cleanup; } | |||
1601 | (PKIX_PRGETHOSTBYNAMEREJECTSHOSTNAMEARGUMENT){ { if (pkixLoggersErrors) { pkix_Logger_CheckWithCode(pkixLoggersErrors , PKIX_PRGETHOSTBYNAMEREJECTSHOSTNAMEARGUMENT, ((void*)0), stdVars .aPkixType, 2, plContext); } } stdVars.aPkixErrorReceived = ( (PKIX_Boolean) 1); stdVars.aPkixErrorCode = PKIX_PRGETHOSTBYNAMEREJECTSHOSTNAMEARGUMENT ; goto cleanup; }; | |||
1602 | } | |||
1603 | } | |||
1604 | ||||
1605 | netAddr.inet.family = PR_AF_INET2; | |||
1606 | netAddr.inet.port = PR_htons(portnum); | |||
1607 | ||||
1608 | if (isServer) { | |||
1609 | ||||
1610 | netAddr.inet.ip = PR_htonl(PR_INADDR_ANY((in_addr_t) 0x00000000)); | |||
1611 | ||||
1612 | } else { | |||
1613 | ||||
1614 | hostenum = PR_EnumerateHostEnt(0, &hostent, portnum, &netAddr); | |||
1615 | if (hostenum == -1) { | |||
1616 | PKIX_ERROR(PKIX_PRENUMERATEHOSTENTFAILED){ { if (pkixLoggersErrors) { pkix_Logger_CheckWithCode(pkixLoggersErrors , PKIX_PRENUMERATEHOSTENTFAILED, ((void*)0), stdVars.aPkixType , 2, plContext); } } stdVars.aPkixErrorReceived = ((PKIX_Boolean ) 1); stdVars.aPkixErrorCode = PKIX_PRENUMERATEHOSTENTFAILED; goto cleanup; }; | |||
1617 | } | |||
1618 | } | |||
1619 | ||||
1620 | PKIX_CHECK(PKIX_PL_Object_Allocdo { stdVars.aPkixErrorResult = (PKIX_PL_Object_Alloc (PKIX_SOCKET_TYPE , sizeof (PKIX_PL_Socket), (PKIX_PL_Object **)&socket, plContext )); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode = PKIX_COULDNOTCREATESOCKETOBJECT; goto cleanup; } } while ( 0) | |||
1621 | (PKIX_SOCKET_TYPE,do { stdVars.aPkixErrorResult = (PKIX_PL_Object_Alloc (PKIX_SOCKET_TYPE , sizeof (PKIX_PL_Socket), (PKIX_PL_Object **)&socket, plContext )); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode = PKIX_COULDNOTCREATESOCKETOBJECT; goto cleanup; } } while ( 0) | |||
1622 | sizeof (PKIX_PL_Socket),do { stdVars.aPkixErrorResult = (PKIX_PL_Object_Alloc (PKIX_SOCKET_TYPE , sizeof (PKIX_PL_Socket), (PKIX_PL_Object **)&socket, plContext )); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode = PKIX_COULDNOTCREATESOCKETOBJECT; goto cleanup; } } while ( 0) | |||
1623 | (PKIX_PL_Object **)&socket,do { stdVars.aPkixErrorResult = (PKIX_PL_Object_Alloc (PKIX_SOCKET_TYPE , sizeof (PKIX_PL_Socket), (PKIX_PL_Object **)&socket, plContext )); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode = PKIX_COULDNOTCREATESOCKETOBJECT; goto cleanup; } } while ( 0) | |||
1624 | plContext),do { stdVars.aPkixErrorResult = (PKIX_PL_Object_Alloc (PKIX_SOCKET_TYPE , sizeof (PKIX_PL_Socket), (PKIX_PL_Object **)&socket, plContext )); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode = PKIX_COULDNOTCREATESOCKETOBJECT; goto cleanup; } } while ( 0) | |||
1625 | PKIX_COULDNOTCREATESOCKETOBJECT)do { stdVars.aPkixErrorResult = (PKIX_PL_Object_Alloc (PKIX_SOCKET_TYPE , sizeof (PKIX_PL_Socket), (PKIX_PL_Object **)&socket, plContext )); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode = PKIX_COULDNOTCREATESOCKETOBJECT; goto cleanup; } } while ( 0); | |||
1626 | ||||
1627 | socket->isServer = isServer; | |||
1628 | socket->timeout = timeout; | |||
1629 | socket->clientSock = NULL((void*)0); | |||
1630 | socket->serverSock = NULL((void*)0); | |||
1631 | socket->netAddr = &netAddr; | |||
1632 | ||||
1633 | socket->callbackList.listenCallback = pkix_pl_Socket_Listen; | |||
1634 | socket->callbackList.acceptCallback = pkix_pl_Socket_Accept; | |||
1635 | socket->callbackList.connectcontinueCallback = | |||
1636 | pkix_pl_Socket_ConnectContinue; | |||
1637 | socket->callbackList.sendCallback = pkix_pl_Socket_Send; | |||
1638 | socket->callbackList.recvCallback = pkix_pl_Socket_Recv; | |||
1639 | socket->callbackList.pollCallback = pkix_pl_Socket_Poll; | |||
1640 | socket->callbackList.shutdownCallback = pkix_pl_Socket_Shutdown; | |||
1641 | ||||
1642 | if (isServer) { | |||
1643 | PKIX_CHECK(pkix_pl_Socket_CreateServer(socket, plContext),do { stdVars.aPkixErrorResult = (pkix_pl_Socket_CreateServer( socket, plContext)); if (stdVars.aPkixErrorResult) { stdVars. aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars .aPkixErrorCode = PKIX_SOCKETCREATESERVERFAILED; goto cleanup ; } } while (0) | |||
1644 | PKIX_SOCKETCREATESERVERFAILED)do { stdVars.aPkixErrorResult = (pkix_pl_Socket_CreateServer( socket, plContext)); if (stdVars.aPkixErrorResult) { stdVars. aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars .aPkixErrorCode = PKIX_SOCKETCREATESERVERFAILED; goto cleanup ; } } while (0); | |||
1645 | *pStatus = 0; | |||
1646 | } else { | |||
1647 | PKIX_CHECK(pkix_pl_Socket_CreateClient(socket, plContext),do { stdVars.aPkixErrorResult = (pkix_pl_Socket_CreateClient( socket, plContext)); if (stdVars.aPkixErrorResult) { stdVars. aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars .aPkixErrorCode = PKIX_SOCKETCREATECLIENTFAILED; goto cleanup ; } } while (0) | |||
1648 | PKIX_SOCKETCREATECLIENTFAILED)do { stdVars.aPkixErrorResult = (pkix_pl_Socket_CreateClient( socket, plContext)); if (stdVars.aPkixErrorResult) { stdVars. aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars .aPkixErrorCode = PKIX_SOCKETCREATECLIENTFAILED; goto cleanup ; } } while (0); | |||
1649 | PKIX_CHECK(pkix_pl_Socket_Connect(socket, pStatus, plContext),do { stdVars.aPkixErrorResult = (pkix_pl_Socket_Connect(socket , pStatus, plContext)); if (stdVars.aPkixErrorResult) { stdVars .aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars .aPkixErrorCode = PKIX_SOCKETCONNECTFAILED; goto cleanup; } } while (0) | |||
1650 | PKIX_SOCKETCONNECTFAILED)do { stdVars.aPkixErrorResult = (pkix_pl_Socket_Connect(socket , pStatus, plContext)); if (stdVars.aPkixErrorResult) { stdVars .aPkixErrorClass = stdVars.aPkixErrorResult->errClass; stdVars .aPkixErrorCode = PKIX_SOCKETCONNECTFAILED; goto cleanup; } } while (0); | |||
1651 | } | |||
1652 | ||||
1653 | *pSocket = socket; | |||
1654 | ||||
1655 | cleanup: | |||
1656 | if (PKIX_ERROR_RECEIVED(stdVars.aPkixErrorReceived || stdVars.aPkixErrorResult || stdVars .aPkixTempErrorReceived || stdVars.aPkixErrorList)) { | |||
1657 | PKIX_DECREF(socket)do { if (socket){ stdVars.aPkixTempResult = PKIX_PL_Object_DecRef ((PKIX_PL_Object *)(socket), plContext); if (stdVars.aPkixTempResult ) { PKIX_DoAddError(&stdVars, stdVars.aPkixTempResult, plContext ); stdVars.aPkixTempResult = ((void*)0); } socket = ((void*)0 ); } } while (0); | |||
1658 | } | |||
1659 | ||||
1660 | PKIX_RETURN(SOCKET)return PKIX_DoReturn(&stdVars, (PKIX_SOCKET_ERROR), ((PKIX_Boolean ) 1), plContext);; | |||
1661 | } | |||
1662 | ||||
1663 | /* | |||
1664 | * FUNCTION: pkix_pl_Socket_GetCallbackList | |||
1665 | */ | |||
1666 | PKIX_Error * | |||
1667 | pkix_pl_Socket_GetCallbackList( | |||
1668 | PKIX_PL_Socket *socket, | |||
1669 | PKIX_PL_Socket_Callback **pCallbackList, | |||
1670 | void *plContext) | |||
1671 | { | |||
1672 | PKIX_ENTER(SOCKET, "pkix_pl_Socket_GetCallbackList")static const char cMyFuncName[] = {"pkix_pl_Socket_GetCallbackList" }; PKIX_StdVars stdVars = zeroStdVars; stdVars.aMyFuncName = cMyFuncName ; stdVars.aPkixType = PKIX_SOCKET_ERROR; ; do { if (pkixLoggersDebugTrace ) { pkix_Logger_Check(pkixLoggersDebugTrace, stdVars.aMyFuncName , ">>>", stdVars.aPkixType, 5, plContext); } } while (0);; | |||
1673 | PKIX_NULLCHECK_TWO(socket, pCallbackList)do { if (((socket) == ((void*)0)) || ((pCallbackList) == ((void *)0))){ stdVars.aPkixErrorReceived = ((PKIX_Boolean) 1); stdVars .aPkixErrorCode = PKIX_NULLARGUMENT; return PKIX_DoReturn(& stdVars, (PKIX_FATAL_ERROR), ((PKIX_Boolean) 1), plContext);; } } while (0); | |||
1674 | ||||
1675 | *pCallbackList = &(socket->callbackList); | |||
1676 | ||||
1677 | PKIX_RETURN(SOCKET)return PKIX_DoReturn(&stdVars, (PKIX_SOCKET_ERROR), ((PKIX_Boolean ) 1), plContext);; | |||
1678 | } | |||
1679 | ||||
1680 | /* | |||
1681 | * FUNCTION: pkix_pl_Socket_GetPRFileDesc | |||
1682 | */ | |||
1683 | PKIX_Error * | |||
1684 | pkix_pl_Socket_GetPRFileDesc( | |||
1685 | PKIX_PL_Socket *socket, | |||
1686 | PRFileDesc **pDesc, | |||
1687 | void *plContext) | |||
1688 | { | |||
1689 | PKIX_ENTER(SOCKET, "pkix_pl_Socket_GetPRFileDesc")static const char cMyFuncName[] = {"pkix_pl_Socket_GetPRFileDesc" }; PKIX_StdVars stdVars = zeroStdVars; stdVars.aMyFuncName = cMyFuncName ; stdVars.aPkixType = PKIX_SOCKET_ERROR; ; do { if (pkixLoggersDebugTrace ) { pkix_Logger_Check(pkixLoggersDebugTrace, stdVars.aMyFuncName , ">>>", stdVars.aPkixType, 5, plContext); } } while (0);; | |||
1690 | PKIX_NULLCHECK_TWO(socket, pDesc)do { if (((socket) == ((void*)0)) || ((pDesc) == ((void*)0))) { stdVars.aPkixErrorReceived = ((PKIX_Boolean) 1); stdVars.aPkixErrorCode = PKIX_NULLARGUMENT; return PKIX_DoReturn(&stdVars, (PKIX_FATAL_ERROR ), ((PKIX_Boolean) 1), plContext);; } } while (0); | |||
1691 | ||||
1692 | *pDesc = socket->clientSock; | |||
1693 | ||||
1694 | PKIX_RETURN(SOCKET)return PKIX_DoReturn(&stdVars, (PKIX_SOCKET_ERROR), ((PKIX_Boolean ) 1), plContext);; | |||
1695 | } |