aboutsummaryrefslogtreecommitdiff
path: root/src/util/service.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2011-12-06 17:58:40 +0000
committerChristian Grothoff <christian@grothoff.org>2011-12-06 17:58:40 +0000
commitd234059375e77fe46c57e98751dc8491dff46e85 (patch)
treef2c73e373b9e7a01af71b2fa1ba0d5feb41881cf /src/util/service.c
parentafa1f268d5275e134566924a84e05ce631396cdb (diff)
downloadgnunet-d234059375e77fe46c57e98751dc8491dff46e85.tar.gz
gnunet-d234059375e77fe46c57e98751dc8491dff46e85.zip
Implement passing sockets in IPC on W32 (#1975)
Diffstat (limited to 'src/util/service.c')
-rw-r--r--src/util/service.c89
1 files changed, 89 insertions, 0 deletions
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 */
1087static int
1088receive_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) &&