diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/arm/do_start_process.c | 2 | ||||
-rw-r--r-- | src/arm/gnunet-service-arm.c | 4 | ||||
-rw-r--r-- | src/arm/gnunet-service-arm.h | 2 | ||||
-rw-r--r-- | src/arm/gnunet-service-arm_interceptor.c | 12 | ||||
-rw-r--r-- | src/include/gnunet_network_lib.h | 5 | ||||
-rw-r--r-- | src/include/gnunet_os_lib.h | 2 | ||||
-rw-r--r-- | src/include/platform.h | 8 | ||||
-rw-r--r-- | src/util/network.c | 15 | ||||
-rw-r--r-- | src/util/os_priority.c | 133 | ||||
-rw-r--r-- | src/util/service.c | 89 |
10 files changed, 250 insertions, 22 deletions
diff --git a/src/arm/do_start_process.c b/src/arm/do_start_process.c index 19b3bc224..f4d3424ff 100644 --- a/src/arm/do_start_process.c +++ b/src/arm/do_start_process.c | |||
@@ -13,7 +13,7 @@ | |||
13 | * @return PID of the started process, -1 on error | 13 | * @return PID of the started process, -1 on error |
14 | */ | 14 | */ |
15 | static struct GNUNET_OS_Process * | 15 | static struct GNUNET_OS_Process * |
16 | do_start_process (const int *lsocks, const char *first_arg, ...) | 16 | do_start_process (const SOCKTYPE *lsocks, const char *first_arg, ...) |
17 | { | 17 | { |
18 | va_list ap; | 18 | va_list ap; |
19 | char **argv; | 19 | char **argv; |
diff --git a/src/arm/gnunet-service-arm.c b/src/arm/gnunet-service-arm.c index 718d90280..d99020d84 100644 --- a/src/arm/gnunet-service-arm.c +++ b/src/arm/gnunet-service-arm.c | |||
@@ -331,7 +331,7 @@ free_service (struct ServiceList *pos) | |||
331 | * @param lsocks -1 terminated list of listen sockets to pass (systemd style), or NULL | 331 | * @param lsocks -1 terminated list of listen sockets to pass (systemd style), or NULL |
332 | */ | 332 | */ |
333 | static void | 333 | static void |
334 | start_process (struct ServiceList *sl, const int *lsocks) | 334 | start_process (struct ServiceList *sl, const SOCKTYPE *lsocks) |
335 | { | 335 | { |
336 | char *loprefix; | 336 | char *loprefix; |
337 | char *options; | 337 | char *options; |
@@ -422,7 +422,7 @@ start_process (struct ServiceList *sl, const int *lsocks) | |||
422 | */ | 422 | */ |
423 | int | 423 | int |
424 | start_service (struct GNUNET_SERVER_Client *client, const char *servicename, | 424 | start_service (struct GNUNET_SERVER_Client *client, const char *servicename, |
425 | const int *lsocks) | 425 | const SOCKTYPE *lsocks) |
426 | { | 426 | { |
427 | struct ServiceList *sl; | 427 | struct ServiceList *sl; |
428 | char *binary; | 428 | char *binary; |
diff --git a/src/arm/gnunet-service-arm.h b/src/arm/gnunet-service-arm.h index 689f26c82..8b17ec816 100644 --- a/src/arm/gnunet-service-arm.h +++ b/src/arm/gnunet-service-arm.h | |||
@@ -37,7 +37,7 @@ | |||
37 | */ | 37 | */ |
38 | int | 38 | int |
39 | start_service (struct GNUNET_SERVER_Client *client, const char *servicename, | 39 | start_service (struct GNUNET_SERVER_Client *client, const char *servicename, |
40 | const int *lsocks); | 40 | const SOCKTYPE *lsocks); |
41 | 41 | ||
42 | /** | 42 | /** |
43 | * Stop listening for connections to a service. | 43 | * Stop listening for connections to a service. |
diff --git a/src/arm/gnunet-service-arm_interceptor.c b/src/arm/gnunet-service-arm_interceptor.c index c5a5fa56b..b4032a153 100644 --- a/src/arm/gnunet-service-arm_interceptor.c +++ b/src/arm/gnunet-service-arm_interceptor.c | |||
@@ -980,9 +980,9 @@ acceptConnection (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
980 | struct ServiceListeningInfo *sli = cls; | 980 | struct ServiceListeningInfo *sli = cls; |
981 | struct ServiceListeningInfo *pos; | 981 | struct ServiceListeningInfo *pos; |
982 | struct ServiceListeningInfo *next; | 982 | struct ServiceListeningInfo *next; |
983 | int *lsocks; | 983 | SOCKTYPE *lsocks; |
984 | unsigned int ls; | 984 | unsigned int ls; |
985 | int use_lsocks; | 985 | int disable_lsocks; |
986 | 986 | ||
987 | sli->acceptTask = GNUNET_SCHEDULER_NO_TASK; | 987 | sli->acceptTask = GNUNET_SCHEDULER_NO_TASK; |
988 | if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason)) | 988 | if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason)) |
@@ -1025,11 +1025,19 @@ acceptConnection (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
1025 | GNUNET_NETWORK_get_fd (sli->listeningSocket)); | 1025 | GNUNET_NETWORK_get_fd (sli->listeningSocket)); |
1026 | GNUNET_free (sli->listeningSocket); /* deliberately no closing! */ | 1026 | GNUNET_free (sli->listeningSocket); /* deliberately no closing! */ |
1027 | GNUNET_free (sli->service_addr); | 1027 | GNUNET_free (sli->service_addr); |
1028 | #if WINDOWS | ||
1029 | GNUNET_array_append (lsocks, ls, INVALID_SOCKET); | ||
1030 | #else | ||
1028 | GNUNET_array_append (lsocks, ls, -1); | 1031 | GNUNET_array_append (lsocks, ls, -1); |
1032 | #endif | ||
1029 | start_service (NULL, sli->serviceName, lsocks); | 1033 | start_service (NULL, sli->serviceName, lsocks); |
1030 | ls = 0; | 1034 | ls = 0; |
1031 | while (lsocks[ls] != -1) | 1035 | while (lsocks[ls] != -1) |
1036 | #if WINDOWS | ||
1037 | GNUNET_break (0 == closesocket (lsocks[ls++])); | ||
1038 | #else | ||
1032 | GNUNET_break (0 == close (lsocks[ls++])); | 1039 | GNUNET_break (0 == close (lsocks[ls++])); |
1040 | #endif | ||
1033 | GNUNET_array_grow (lsocks, ls, 0); | 1041 | GNUNET_array_grow (lsocks, ls, 0); |
1034 | GNUNET_free (sli->serviceName); | 1042 | GNUNET_free (sli->serviceName); |
1035 | GNUNET_free (sli); | 1043 | GNUNET_free (sli); |
diff --git a/src/include/gnunet_network_lib.h b/src/include/gnunet_network_lib.h index 65b2042d5..a14d5f0bb 100644 --- a/src/include/gnunet_network_lib.h +++ b/src/include/gnunet_network_lib.h | |||
@@ -96,7 +96,7 @@ GNUNET_NETWORK_socket_accept (const struct GNUNET_NETWORK_Handle *desc, | |||
96 | * @return NULL on error (including not supported on target platform) | 96 | * @return NULL on error (including not supported on target platform) |
97 | */ | 97 | */ |
98 | struct GNUNET_NETWORK_Handle * | 98 | struct GNUNET_NETWORK_Handle * |
99 | GNUNET_NETWORK_socket_box_native (int fd); | 99 | GNUNET_NETWORK_socket_box_native (SOCKTYPE fd); |
100 | 100 | ||
101 | 101 | ||
102 | /** | 102 | /** |
@@ -320,8 +320,7 @@ GNUNET_NETWORK_fdset_set (struct GNUNET_NETWORK_FDSet *fds, | |||
320 | const struct GNUNET_NETWORK_Handle *desc); | 320 | const struct GNUNET_NETWORK_Handle *desc); |
321 | 321 | ||
322 | 322 | ||
323 | #ifdef __MINGW32__ | 323 | #if WINDOWS |
324 | /* TODO: maybe #ifdef WINDOWS? -ndurner */ | ||
325 | /** | 324 | /** |
326 | * Add a W32 file handle to the fd set | 325 | * Add a W32 file handle to the fd set |
327 | * @param fds fd set | 326 | * @param fds fd set |
diff --git a/src/include/gnunet_os_lib.h b/src/include/gnunet_os_lib.h index aed5e3b01..ff324e18a 100644 --- a/src/include/gnunet_os_lib.h +++ b/src/include/gnunet_os_lib.h | |||
@@ -275,7 +275,7 @@ GNUNET_OS_start_process_va (struct GNUNET_DISK_PipeHandle *pipe_stdin, | |||
275 | * @return pointer to process structure of the new process, NULL on error | 275 | * @return pointer to process structure of the new process, NULL on error |
276 | */ | 276 | */ |
277 | struct GNUNET_OS_Process * | 277 | struct GNUNET_OS_Process * |
278 | GNUNET_OS_start_process_v (const int *lsocks, const char *filename, | 278 | GNUNET_OS_start_process_v (const SOCKTYPE *lsocks, const char *filename, |
279 | char *const argv[]); | 279 | char *const argv[]); |
280 | 280 | ||
281 | 281 | ||
diff --git a/src/include/platform.h b/src/include/platform.h index 0aa59b72f..179503731 100644 --- a/src/include/platform.h +++ b/src/include/platform.h | |||
@@ -246,4 +246,12 @@ atoll (const char *nptr); | |||
246 | #define MAKE_UNALIGNED(val) val | 246 | #define MAKE_UNALIGNED(val) val |
247 | #endif | 247 | #endif |
248 | 248 | ||
249 | #if WINDOWS | ||
250 | #define FDTYPE HANDLE | ||
251 | #define SOCKTYPE SOCKET | ||
252 | #else | ||
253 | #define FDTYPE int | ||
254 | #define SOCKTYPE int | ||
255 | #endif | ||
256 | |||
249 | #endif | 257 | #endif |
diff --git a/src/util/network.c b/src/util/network.c index c4861ecfa..d8c64276b 100644 --- a/src/util/network.c +++ b/src/util/network.c | |||
@@ -377,13 +377,20 @@ GNUNET_NETWORK_socket_close (struct GNUNET_NETWORK_Handle *desc) | |||
377 | * @return NULL on error (including not supported on target platform) | 377 | * @return NULL on error (including not supported on target platform) |
378 | */ | 378 | */ |
379 | struct GNUNET_NETWORK_Handle * | 379 | struct GNUNET_NETWORK_Handle * |
380 | GNUNET_NETWORK_socket_box_native (int fd) | 380 | GNUNET_NETWORK_socket_box_native (SOCKTYPE fd) |
381 | { | 381 | { |
382 | struct GNUNET_NETWORK_Handle *ret; | ||
382 | #if MINGW | 383 | #if MINGW |
383 | return NULL; | 384 | unsigned long i; |
385 | DWORD d; | ||
386 | /* FIXME: Find a better call to check that FD is valid */ | ||
387 | if (WSAIoctl (fd, FIONBIO, (void *) &i, sizeof (i), NULL, 0, &d, NULL, NULL) != 0) | ||
388 | return NULL; /* invalid FD */ | ||
389 | ret = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle)); | ||
390 | ret->fd = fd; | ||
391 | ret->af = AF_UNSPEC; | ||
392 | return ret; | ||
384 | #else | 393 | #else |
385 | struct GNUNET_NETWORK_Handle *ret; | ||
386 | |||
387 | if (fcntl (fd, F_GETFD) < 0) | 394 | if (fcntl (fd, F_GETFD) < 0) |
388 | return NULL; /* invalid FD */ | 395 | return NULL; /* invalid FD */ |
389 | ret = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle)); | 396 | ret = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle)); |
diff --git a/src/util/os_priority.c b/src/util/os_priority.c index 9ffa190fa..de3a5757e 100644 --- a/src/util/os_priority.c +++ b/src/util/os_priority.c | |||
@@ -852,7 +852,8 @@ GNUNET_OS_start_process (struct GNUNET_DISK_PipeHandle *pipe_stdin, | |||
852 | * @return process ID of the new process, -1 on error | 852 | * @return process ID of the new process, -1 on error |
853 | */ | 853 | */ |
854 | struct GNUNET_OS_Process * | 854 | struct GNUNET_OS_Process * |
855 | GNUNET_OS_start_process_v (const int *lsocks, const char *filename, | 855 | GNUNET_OS_start_process_v (const SOCKTYPE *lsocks, |
856 | const char *filename, | ||
856 | char *const argv[]) | 857 | char *const argv[]) |
857 | { | 858 | { |
858 | #if ENABLE_WINDOWS_WORKAROUNDS | 859 | #if ENABLE_WINDOWS_WORKAROUNDS |
@@ -979,7 +980,7 @@ GNUNET_OS_start_process_v (const int *lsocks, const char *filename, | |||
979 | 980 | ||
980 | char path[MAX_PATH + 1]; | 981 | char path[MAX_PATH + 1]; |
981 | 982 | ||
982 | char *our_env[3] = { NULL, NULL, NULL }; | 983 | char *our_env[5] = { NULL, NULL, NULL, NULL, NULL }; |
983 | char *env_block = NULL; | 984 | char *env_block = NULL; |
984 | char *pathbuf; | 985 | char *pathbuf; |
985 | DWORD pathbuf_len, alloc_len; | 986 | DWORD pathbuf_len, alloc_len; |
@@ -988,8 +989,12 @@ GNUNET_OS_start_process_v (const int *lsocks, const char *filename, | |||
988 | char *libdir; | 989 | char *libdir; |
989 | char *ptr; | 990 | char *ptr; |
990 | char *non_const_filename; | 991 | char *non_const_filename; |
992 | struct GNUNET_DISK_PipeHandle *lsocks_pipe; | ||
993 | const struct GNUNET_DISK_FileHandle *lsocks_write_fd; | ||
994 | HANDLE lsocks_read; | ||
995 | HANDLE lsocks_write; | ||
991 | 996 | ||
992 | GNUNET_assert (lsocks == NULL); | 997 | int fail; |
993 | 998 | ||
994 | /* Search in prefix dir (hopefully - the directory from which | 999 | /* Search in prefix dir (hopefully - the directory from which |
995 | * the current module was loaded), bindir and libdir, then in PATH | 1000 | * the current module was loaded), bindir and libdir, then in PATH |
@@ -1103,6 +1108,25 @@ GNUNET_OS_start_process_v (const int *lsocks, const char *filename, | |||
1103 | GNUNET_free (path); | 1108 | GNUNET_free (path); |
1104 | return NULL; | 1109 | return NULL; |
1105 | } | 1110 | } |
1111 | if (lsocks != NULL) | ||
1112 | { | ||
1113 | lsocks_pipe = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO); | ||
1114 | |||
1115 | if (lsocks_pipe == NULL) | ||
1116 | { | ||
1117 | GNUNET_free (cmd); | ||
1118 | GNUNET_free (path); | ||
1119 | GNUNET_DISK_pipe_close (lsocks_pipe); | ||
1120 | return NULL; | ||
1121 | } | ||
1122 | lsocks_write_fd = GNUNET_DISK_pipe_handle (lsocks_pipe, | ||
1123 | GNUNET_DISK_PIPE_END_WRITE); | ||
1124 | GNUNET_DISK_internal_file_handle_ (lsocks_write_fd, | ||
1125 | &lsocks_write, sizeof (HANDLE)); | ||
1126 | GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle | ||
1127 | (lsocks_pipe, GNUNET_DISK_PIPE_END_READ), | ||
1128 | &lsocks_read, sizeof (HANDLE)); | ||
1129 | } | ||
1106 | 1130 | ||
1107 | #if DEBUG_OS | 1131 | #if DEBUG_OS |
1108 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Opened the parent end of the pipe `%s'\n", | 1132 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Opened the parent end of the pipe `%s'\n", |
@@ -1111,17 +1135,31 @@ GNUNET_OS_start_process_v (const int *lsocks, const char *filename, | |||
1111 | 1135 | ||
1112 | GNUNET_asprintf (&our_env[0], "%s=", GNUNET_OS_CONTROL_PIPE); | 1136 | GNUNET_asprintf (&our_env[0], "%s=", GNUNET_OS_CONTROL_PIPE); |
1113 | GNUNET_asprintf (&our_env[1], "%s", childpipename); | 1137 | GNUNET_asprintf (&our_env[1], "%s", childpipename); |
1114 | our_env[2] = NULL; | 1138 | GNUNET_free (childpipename); |
1139 | if (lsocks == NULL) | ||
1140 | our_env[2] = NULL; | ||
1141 | else | ||
1142 | { | ||
1143 | /*This will tell the child that we're going to send lsocks over the pipe*/ | ||
1144 | GNUNET_asprintf (&our_env[2], "%s=", "GNUNET_OS_READ_LSOCKS"); | ||
1145 | GNUNET_asprintf (&our_env[3], "%lu", lsocks_read); | ||
1146 | our_env[4] = NULL; | ||
1147 | } | ||
1115 | env_block = CreateCustomEnvTable (our_env); | 1148 | env_block = CreateCustomEnvTable (our_env); |
1116 | GNUNET_free (our_env[0]); | 1149 | GNUNET_free_non_null (our_env[0]); |
1117 | GNUNET_free (our_env[1]); | 1150 | GNUNET_free_non_null (our_env[1]); |
1151 | GNUNET_free_non_null (our_env[2]); | ||
1152 | GNUNET_free_non_null (our_env[3]); | ||
1118 | 1153 | ||
1119 | if (!CreateProcess | 1154 | if (!CreateProcessA |
1120 | (path, cmd, NULL, NULL, FALSE, DETACHED_PROCESS | CREATE_SUSPENDED, | 1155 | (path, cmd, NULL, NULL, TRUE, DETACHED_PROCESS | CREATE_SUSPENDED, |
1121 | env_block, NULL, &start, &proc)) | 1156 | env_block, NULL, &start, &proc)) |
1122 | { | 1157 | { |
1123 | SetErrnoFromWinError (GetLastError ()); | 1158 | SetErrnoFromWinError (GetLastError ()); |
1124 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "CreateProcess"); | 1159 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "CreateProcess"); |
1160 | GNUNET_DISK_npipe_close (control_pipe); | ||
1161 | if (lsocks != NULL) | ||
1162 | GNUNET_DISK_pipe_close (lsocks_pipe); | ||
1125 | GNUNET_free (env_block); | 1163 | GNUNET_free (env_block); |
1126 | GNUNET_free (cmd); | 1164 | GNUNET_free (cmd); |
1127 | return NULL; | 1165 | return NULL; |
@@ -1140,6 +1178,85 @@ GNUNET_OS_start_process_v (const int *lsocks, const char *filename, | |||
1140 | CloseHandle (proc.hThread); | 1178 | CloseHandle (proc.hThread); |
1141 | GNUNET_free (cmd); | 1179 | GNUNET_free (cmd); |
1142 | 1180 | ||
1181 | if (lsocks == NULL) | ||
1182 | return gnunet_proc; | ||
1183 | |||
1184 | GNUNET_DISK_pipe_close_end (lsocks_pipe, GNUNET_DISK_PIPE_END_READ); | ||
1185 | |||
1186 | /* This is a replacement for "goto error" that doesn't use goto */ | ||
1187 | fail = 1; | ||
1188 | do | ||
1189 | { | ||
1190 | int wrote; | ||
1191 | uint64_t size, count, i; | ||
1192 | |||
1193 | /* Tell the number of sockets */ | ||
1194 | for (count = 0; lsocks && lsocks[count] != INVALID_SOCKET; count++); | ||
1195 | |||
1196 | wrote = GNUNET_DISK_file_write (lsocks_write_fd, &count, sizeof (count)); | ||
1197 | if (wrote != sizeof (count)) | ||
1198 | { | ||
1199 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to write %u count bytes to the child: %u\n", sizeof (count), GetLastError ()); | ||
1200 | break; | ||
1201 | } | ||
1202 | for (i = 0; lsocks && lsocks[i] != INVALID_SOCKET; i++) | ||
1203 | { | ||
1204 | WSAPROTOCOL_INFOA pi; | ||
1205 | /* Get a socket duplication info */ | ||
1206 | if (SOCKET_ERROR == WSADuplicateSocketA (lsocks[i], gnunet_proc->pid, &pi)) | ||
1207 | { | ||
1208 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to duplicate an socket[%llu]: %u\n", i, GetLastError ()); | ||
1209 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "CreateProcess"); | ||
1210 | break; | ||
1211 | } | ||
1212 | /* Synchronous I/O is not nice, but we can't schedule this: | ||
1213 | * lsocks will be closed/freed by the caller soon, and until | ||
1214 | * the child creates a duplicate, closing a socket here will | ||
1215 | * close it for good. | ||
1216 | */ | ||
1217 | /* Send the size of the structure | ||
1218 | * (the child might be built with different headers...) | ||
1219 | */ | ||
1220 | size = sizeof (pi); | ||
1221 | wrote = GNUNET_DISK_file_write (lsocks_write_fd, &size, sizeof (size)); | ||
1222 | if (wrote != sizeof (size)) | ||
1223 | { | ||
1224 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to write %u size[%llu] bytes to the child: %u\n", sizeof (size), i, GetLastError ()); | ||
1225 | break; | ||
1226 | } | ||
1227 | /* Finally! Send the data */ | ||
1228 | wrote = GNUNET_DISK_file_write (lsocks_write_fd, &pi, sizeof (pi)); | ||
1229 | if (wrote != sizeof (pi)) | ||
1230 | { | ||
1231 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to write %u socket[%llu] bytes to the child: %u\n", sizeof (pi), i, GetLastError ()); | ||
1232 | break; | ||
1233 | } | ||
1234 | } | ||
1235 | /* This will block us until the child makes a final read or closes | ||
1236 | * the pipe (hence no 'wrote' check), since we have to wait for it | ||
1237 | * to duplicate the last socket, before we return and start closing | ||
1238 | * our own copies) | ||
1239 | */ | ||
1240 | wrote = GNUNET_DISK_file_write (lsocks_write_fd, &count, sizeof (count)); | ||
1241 | fail = 0; | ||
1242 | } | ||
1243 | while (fail); | ||
1244 | |||
1245 | GNUNET_DISK_file_sync (lsocks_write_fd); | ||
1246 | GNUNET_DISK_pipe_close (lsocks_pipe); | ||
1247 | |||
1248 | if (fail) | ||
1249 | { | ||
1250 | /* If we can't pass on the socket(s), the child will block forever, | ||
1251 | * better put it out of its misery. | ||
1252 | */ | ||
1253 | TerminateProcess (gnunet_proc->handle, 0); | ||
1254 | CloseHandle (gnunet_proc->handle); | ||
1255 | GNUNET_DISK_npipe_close (gnunet_proc->control_pipe); | ||
1256 | GNUNET_free (gnunet_proc); | ||
1257 | return NULL; | ||
1258 | } | ||
1259 | |||
1143 | return gnunet_proc; | 1260 | return gnunet_proc; |
1144 | #endif | 1261 | #endif |
1145 | } | 1262 | } |
diff --git a/src/util/service.c b/src/util/service.c index 91fc460e2..d37fe87c2 100644 --- a/src/util/service.c +++ b/src/util/service.c | |||
@@ -1079,6 +1079,89 @@ GNUNET_SERVICE_get_server_addresses (const char *serviceName, | |||
1079 | } | 1079 | } |
1080 | 1080 | ||
1081 | 1081 | ||
1082 | #ifdef MINGW | ||
1083 | /** | ||
1084 | * @return GNUNET_YES if ok, GNUNET_NO if not ok (must bind yourself), | ||
1085 | * and GNUNET_SYSERR on error. | ||
1086 | */ | ||
1087 | static int | ||
1088 | receive_sockets_from_parent (struct GNUNET_SERVICE_Context *sctx) | ||
1089 | { | ||
1090 | const char *env_buf; | ||
1091 | int fail; | ||
1092 | uint64_t count, i; | ||
1093 | HANDLE lsocks_pipe; | ||
1094 | |||
1095 | env_buf = getenv ("GNUNET_OS_READ_LSOCKS"); | ||
1096 | if ((env_buf == NULL) || (strlen (env_buf) <= 0)) | ||
1097 | { | ||
1098 | return GNUNET_NO; | ||
1099 | } | ||
1100 | /* Using W32 API directly here, because this pipe will | ||
1101 | * never be used outside of this function, and it's just too much of a bother | ||
1102 | * to create a GNUnet API that boxes a HANDLE (the way it is done with socks) | ||
1103 | */ | ||
1104 | lsocks_pipe = (HANDLE) strtoul (env_buf, NULL, 10); | ||
1105 | if (lsocks_pipe == 0 || lsocks_pipe == INVALID_HANDLE_VALUE) | ||
1106 | return GNUNET_NO; | ||
1107 | |||
1108 | fail = 1; | ||
1109 | do | ||
1110 | { | ||
1111 | int ret; | ||
1112 | int fail2; | ||
1113 | DWORD rd; | ||
1114 | |||
1115 | ret = ReadFile (lsocks_pipe, &count, sizeof (count), &rd, NULL); | ||
1116 | if (ret == 0 || rd != sizeof (count) || count == 0) | ||
1117 | break; | ||
1118 | sctx->lsocks = | ||
1119 | GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle *) * (count + 1)); | ||
1120 | |||
1121 | fail2 = 1; | ||
1122 | for (i = 0; i < count; i++) | ||
1123 | { | ||
1124 | WSAPROTOCOL_INFOA pi; | ||
1125 | uint64_t size; | ||
1126 | SOCKET s; | ||
1127 | ret = ReadFile (lsocks_pipe, &size, sizeof (size), &rd, NULL); | ||
1128 | if (ret == 0 || rd != sizeof (size) || size != sizeof (pi)) | ||
1129 | break; | ||
1130 | ret = ReadFile (lsocks_pipe, &pi, sizeof (pi), &rd, NULL); | ||
1131 | if (ret == 0 || rd != sizeof (pi)) | ||
1132 | break; | ||
1133 | s = WSASocketA (pi.iAddressFamily, pi.iSocketType, pi.iProtocol, &pi, 0, WSA_FLAG_OVERLAPPED); | ||
1134 | sctx->lsocks[i] = GNUNET_NETWORK_socket_box_native (s); | ||
1135 | if (sctx->lsocks[i] == NULL) | ||
1136 | break; | ||
1137 | else if (i == count - 1) | ||
1138 | fail2 = 0; | ||
1139 | } | ||
1140 | if (fail2) | ||
1141 | break; | ||
1142 | sctx->lsocks[count] = NULL; | ||
1143 | fail = 0; | ||
1144 | } | ||
1145 | while (fail); | ||
1146 | |||
1147 | CloseHandle (lsocks_pipe); | ||
1148 | |||
1149 | if (fail) | ||
1150 | { | ||
1151 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
1152 | _("Could not access a pre-bound socket, will try to bind myself\n")); | ||
1153 | for (i = 0; sctx->lsocks[i] != NULL && i < count; i++) | ||
1154 | GNUNET_break (0 == GNUNET_NETWORK_socket_close (sctx->lsocks[i])); | ||
1155 | GNUNET_free (sctx->lsocks); | ||
1156 | sctx->lsocks = NULL; | ||
1157 | return GNUNET_NO; | ||
1158 | } | ||
1159 | |||
1160 | return GNUNET_YES; | ||
1161 | } | ||
1162 | #endif | ||
1163 | |||
1164 | |||
1082 | /** | 1165 | /** |
1083 | * Setup addr, addrlen, idle_timeout | 1166 | * Setup addr, addrlen, idle_timeout |
1084 | * based on configuration! | 1167 | * based on configuration! |
@@ -1175,6 +1258,12 @@ setup_service (struct GNUNET_SERVICE_Context *sctx) | |||
1175 | unsetenv ("LISTEN_PID"); | 1258 | unsetenv ("LISTEN_PID"); |
1176 | unsetenv ("LISTEN_FDS"); | 1259 | unsetenv ("LISTEN_FDS"); |
1177 | } | 1260 | } |
1261 | #else | ||
1262 | if (getenv ("GNUNET_OS_READ_LSOCKS") != NULL) | ||
1263 | { | ||
1264 | receive_sockets_from_parent (sctx); | ||
1265 | putenv ("GNUNET_OS_READ_LSOCKS="); | ||
1266 | } | ||
1178 | #endif | 1267 | #endif |
1179 | 1268 | ||
1180 | if ((sctx->lsocks == NULL) && | 1269 | if ((sctx->lsocks == NULL) && |