aboutsummaryrefslogtreecommitdiff
path: root/src/util/service.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2011-10-11 09:43:04 +0000
committerChristian Grothoff <christian@grothoff.org>2011-10-11 09:43:04 +0000
commitd9d94d0e53d26af75ec8241383d166544ebd79f3 (patch)
tree9080b73624389403a198257fe0547bb4634e64d2 /src/util/service.c
parent2d792ee2e9cc0c993b8907e2c8edb0c2b8465343 (diff)
downloadgnunet-d9d94d0e53d26af75ec8241383d166544ebd79f3.tar.gz
gnunet-d9d94d0e53d26af75ec8241383d166544ebd79f3.zip
converting to GNUNET_LOG_from*
Diffstat (limited to 'src/util/service.c')
-rw-r--r--src/util/service.c1433
1 files changed, 725 insertions, 708 deletions
diff --git a/src/util/service.c b/src/util/service.c
index 15937e117..7cafe35c8 100644
--- a/src/util/service.c
+++ b/src/util/service.c
@@ -36,6 +36,12 @@
36#include "gnunet_server_lib.h" 36#include "gnunet_server_lib.h"
37#include "gnunet_service_lib.h" 37#include "gnunet_service_lib.h"
38 38
39#define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
40
41#define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util", syscall)
42
43#define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util", syscall, filename)
44
39#define DEBUG_SERVICE GNUNET_EXTRA_LOGGING 45#define DEBUG_SERVICE GNUNET_EXTRA_LOGGING
40 46
41/* ******************* access control ******************** */ 47/* ******************* access control ******************** */
@@ -98,120 +104,121 @@ parse_ipv4_specification (const char *routeList)
98 i = 0; 104 i = 0;
99 pos = 0; 105 pos = 0;
100 while (i < count) 106 while (i < count)
101 {
102 cnt =
103 sscanf (&routeList[pos], "%u.%u.%u.%u/%u.%u.%u.%u;", &temps[0],
104 &temps[1], &temps[2], &temps[3], &temps[4], &temps[5],
105 &temps[6], &temps[7]);
106 if (cnt == 8)
107 {
108 for (j = 0; j < 8; j++)
109 if (temps[j] > 0xFF)
110 {
111 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
112 _("Invalid format for IP: `%s'\n"), &routeList[pos]);
113 GNUNET_free (result);
114 return NULL;
115 }
116 result[i].network.s_addr =
117 htonl ((temps[0] << 24) + (temps[1] << 16) + (temps[2] << 8) +
118 temps[3]);
119 result[i].netmask.s_addr =
120 htonl ((temps[4] << 24) + (temps[5] << 16) + (temps[6] << 8) +
121 temps[7]);
122 while (routeList[pos] != ';')
123 pos++;
124 pos++;
125 i++;
126 continue;
127 }
128 /* try second notation */
129 cnt =
130 sscanf (&routeList[pos], "%u.%u.%u.%u/%u;", &temps[0], &temps[1],
131 &temps[2], &temps[3], &slash);
132 if (cnt == 5)
133 { 107 {
134 for (j = 0; j < 4; j++) 108 cnt =
135 if (temps[j] > 0xFF) 109 sscanf (&routeList[pos], "%u.%u.%u.%u/%u.%u.%u.%u;", &temps[0],
136 { 110 &temps[1], &temps[2], &temps[3], &temps[4], &temps[5],
137 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 111 &temps[6], &temps[7]);
138 _("Invalid format for IP: `%s'\n"), &routeList[pos]); 112 if (cnt == 8)
139 GNUNET_free (result); 113 {
140 return NULL; 114 for (j = 0; j < 8; j++)
141 } 115 if (temps[j] > 0xFF)
142 result[i].network.s_addr = 116 {
143 htonl ((temps[0] << 24) + (temps[1] << 16) + (temps[2] << 8) + 117 LOG (GNUNET_ERROR_TYPE_ERROR,
144 temps[3]); 118 _("Invalid format for IP: `%s'\n"), &routeList[pos]);
145 if ((slash <= 32) && (slash >= 0)) 119 GNUNET_free (result);
146 { 120 return NULL;
147 result[i].netmask.s_addr = 0; 121 }
148 while (slash > 0) 122 result[i].network.s_addr =
149 { 123 htonl ((temps[0] << 24) + (temps[1] << 16) + (temps[2] << 8) +
150 result[i].netmask.s_addr = 124 temps[3]);
151 (result[i].netmask.s_addr >> 1) + 0x80000000; 125 result[i].netmask.s_addr =
152 slash--; 126 htonl ((temps[4] << 24) + (temps[5] << 16) + (temps[6] << 8) +
153 } 127 temps[7]);
154 result[i].netmask.s_addr = htonl (result[i].netmask.s_addr); 128 while (routeList[pos] != ';')
155 while (routeList[pos] != ';') 129 pos++;
156 pos++; 130 pos++;
157 pos++; 131 i++;
158 i++; 132 continue;
159 continue; 133 }
160 } 134 /* try second notation */
161 else 135 cnt =
162 { 136 sscanf (&routeList[pos], "%u.%u.%u.%u/%u;", &temps[0], &temps[1],
163 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 137 &temps[2], &temps[3], &slash);
164 _ 138 if (cnt == 5)
165 ("Invalid network notation ('/%d' is not legal in IPv4 CIDR)."), 139 {
166 slash); 140 for (j = 0; j < 4; j++)
167 GNUNET_free (result); 141 if (temps[j] > 0xFF)
168 return NULL; /* error */ 142 {
169 } 143 LOG (GNUNET_ERROR_TYPE_ERROR,
144 _("Invalid format for IP: `%s'\n"), &routeList[pos]);
145 GNUNET_free (result);
146 return NULL;
147 }
148 result[i].network.s_addr =
149 htonl ((temps[0] << 24) + (temps[1] << 16) + (temps[2] << 8) +
150 temps[3]);
151 if ((slash <= 32) && (slash >= 0))
152 {
153 result[i].netmask.s_addr = 0;
154 while (slash > 0)
155 {
156 result[i].netmask.s_addr =
157 (result[i].netmask.s_addr >> 1) + 0x80000000;
158 slash--;
159 }
160 result[i].netmask.s_addr = htonl (result[i].netmask.s_addr);
161 while (routeList[pos] != ';')
162 pos++;
163 pos++;
164 i++;
165 continue;
166 }
167 else
168 {
169 LOG (GNUNET_ERROR_TYPE_ERROR,
170 _
171 ("Invalid network notation ('/%d' is not legal in IPv4 CIDR)."),
172 slash);
173 GNUNET_free (result);
174 return NULL; /* error */
175 }
176 }
177 /* try third notation */
178 slash = 32;
179 cnt =
180 sscanf (&routeList[pos], "%u.%u.%u.%u;", &temps[0], &temps[1],
181 &temps[2], &temps[3]);
182 if (cnt == 4)
183 {
184 for (j = 0; j < 4; j++)
185 if (temps[j] > 0xFF)
186 {
187 LOG (GNUNET_ERROR_TYPE_ERROR,
188 _("Invalid format for IP: `%s'\n"), &routeList[pos]);
189 GNUNET_free (result);
190 return NULL;
191 }
192 result[i].network.s_addr =
193 htonl ((temps[0] << 24) + (temps[1] << 16) + (temps[2] << 8) +
194 temps[3]);
195 result[i].netmask.s_addr = 0;
196 while (slash > 0)
197 {
198 result[i].netmask.s_addr =
199 (result[i].netmask.s_addr >> 1) + 0x80000000;
200 slash--;
201 }
202 result[i].netmask.s_addr = htonl (result[i].netmask.s_addr);
203 while (routeList[pos] != ';')
204 pos++;
205 pos++;
206 i++;
207 continue;
208 }
209 LOG (GNUNET_ERROR_TYPE_ERROR, _("Invalid format for IP: `%s'\n"),
210 &routeList[pos]);
211 GNUNET_free (result);
212 return NULL; /* error */
170 } 213 }
171 /* try third notation */ 214 if (pos < strlen (routeList))
172 slash = 32;
173 cnt =
174 sscanf (&routeList[pos], "%u.%u.%u.%u;", &temps[0], &temps[1],
175 &temps[2], &temps[3]);
176 if (cnt == 4)
177 { 215 {
178 for (j = 0; j < 4; j++) 216 LOG (GNUNET_ERROR_TYPE_ERROR, _("Invalid format for IP: `%s'\n"),
179 if (temps[j] > 0xFF) 217 &routeList[pos]);
180 { 218 GNUNET_free (result);
181 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 219 return NULL; /* oops */
182 _("Invalid format for IP: `%s'\n"), &routeList[pos]);
183 GNUNET_free (result);
184 return NULL;
185 }
186 result[i].network.s_addr =
187 htonl ((temps[0] << 24) + (temps[1] << 16) + (temps[2] << 8) +
188 temps[3]);
189 result[i].netmask.s_addr = 0;
190 while (slash > 0)
191 {
192 result[i].netmask.s_addr = (result[i].netmask.s_addr >> 1) + 0x80000000;
193 slash--;
194 }
195 result[i].netmask.s_addr = htonl (result[i].netmask.s_addr);
196 while (routeList[pos] != ';')
197 pos++;
198 pos++;
199 i++;
200 continue;
201 } 220 }
202 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Invalid format for IP: `%s'\n"), 221 return result; /* ok */
203 &routeList[pos]);
204 GNUNET_free (result);
205 return NULL; /* error */
206 }
207 if (pos < strlen (routeList))
208 {
209 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Invalid format for IP: `%s'\n"),
210 &routeList[pos]);
211 GNUNET_free (result);
212 return NULL; /* oops */
213 }
214 return result; /* ok */
215} 222}
216 223
217 224
@@ -253,84 +260,85 @@ parse_ipv6_specification (const char *routeListX)
253 if (routeList[i] == ';') 260 if (routeList[i] == ';')
254 count++; 261 count++;
255 if (routeList[len - 1] != ';') 262 if (routeList[len - 1] != ';')
256 { 263 {
257 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 264 LOG (GNUNET_ERROR_TYPE_ERROR,
258 _("Invalid network notation (does not end with ';': `%s')\n"), 265 _("Invalid network notation (does not end with ';': `%s')\n"),
259 routeList); 266 routeList);
260 GNUNET_free (routeList); 267 GNUNET_free (routeList);
261 return NULL; 268 return NULL;
262 } 269 }
263 270
264 result = GNUNET_malloc (sizeof (struct IPv6NetworkSet) * (count + 1)); 271 result = GNUNET_malloc (sizeof (struct IPv6NetworkSet) * (count + 1));
265 memset (result, 0, sizeof (struct IPv6NetworkSet) * (count + 1)); 272 memset (result, 0, sizeof (struct IPv6NetworkSet) * (count + 1));
266 i = 0; 273 i = 0;
267 pos = 0; 274 pos = 0;
268 while (i < count) 275 while (i < count)
269 {
270 start = pos;
271 while (routeList[pos] != ';')
272 pos++;
273 slash = pos;
274 while ((slash >= start) && (routeList[slash] != '/'))
275 slash--;
276 if (slash < start)
277 { 276 {
278 memset (&result[i].netmask, 0xFF, sizeof (struct in6_addr)); 277 start = pos;
278 while (routeList[pos] != ';')
279 pos++;
279 slash = pos; 280 slash = pos;
280 } 281 while ((slash >= start) && (routeList[slash] != '/'))
281 else 282 slash--;
282 { 283 if (slash < start)
283 routeList[pos] = '\0'; 284 {
284 ret = inet_pton (AF_INET6, &routeList[slash + 1], &result[i].netmask); 285 memset (&result[i].netmask, 0xFF, sizeof (struct in6_addr));
285 if (ret <= 0) 286 slash = pos;
286 { 287 }
287 save = errno;
288 if ((1 != SSCANF (&routeList[slash + 1], "%u", &bits)) || (bits >= 128))
289 {
290 if (ret == 0)
291 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
292 _("Wrong format `%s' for netmask\n"),
293 &routeList[slash + 1]);
294 else
295 {
296 errno = save;
297 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "inet_pton");
298 }
299 GNUNET_free (result);
300 GNUNET_free (routeList);
301 return NULL;
302 }
303 off = 0;
304 while (bits > 8)
305 {
306 result[i].netmask.s6_addr[off++] = 0xFF;
307 bits -= 8;
308 }
309 while (bits > 0)
310 {
311 result[i].netmask.s6_addr[off] =
312 (result[i].netmask.s6_addr[off] >> 1) + 0x80;
313 bits--;
314 }
315 }
316 }
317 routeList[slash] = '\0';
318 ret = inet_pton (AF_INET6, &routeList[start], &result[i].network);
319 if (ret <= 0)
320 {
321 if (ret == 0)
322 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
323 _("Wrong format `%s' for network\n"),
324 &routeList[slash + 1]);
325 else 288 else
326 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "inet_pton"); 289 {
327 GNUNET_free (result); 290 routeList[pos] = '\0';
328 GNUNET_free (routeList); 291 ret =
329 return NULL; 292 inet_pton (AF_INET6, &routeList[slash + 1], &result[i].netmask);
293 if (ret <= 0)
294 {
295 save = errno;
296 if ((1 != SSCANF (&routeList[slash + 1], "%u", &bits))
297 || (bits >= 128))
298 {
299 if (ret == 0)
300 LOG (GNUNET_ERROR_TYPE_ERROR,
301 _("Wrong format `%s' for netmask\n"),
302 &routeList[slash + 1]);
303 else
304 {
305 errno = save;
306 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "inet_pton");
307 }
308 GNUNET_free (result);
309 GNUNET_free (routeList);
310 return NULL;
311 }
312 off = 0;
313 while (bits > 8)
314 {
315 result[i].netmask.s6_addr[off++] = 0xFF;
316 bits -= 8;
317 }
318 while (bits > 0)
319 {
320 result[i].netmask.s6_addr[off] =
321 (result[i].netmask.s6_addr[off] >> 1) + 0x80;
322 bits--;
323 }
324 }
325 }
326 routeList[slash] = '\0';
327 ret = inet_pton (AF_INET6, &routeList[start], &result[i].network);
328 if (ret <= 0)
329 {
330 if (ret == 0)
331 LOG (GNUNET_ERROR_TYPE_ERROR,
332 _("Wrong format `%s' for network\n"), &routeList[slash + 1]);
333 else
334 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "inet_pton");
335 GNUNET_free (result);
336 GNUNET_free (routeList);
337 return NULL;
338 }
339 pos++;
340 i++;
330 } 341 }
331 pos++;
332 i++;
333 }
334 GNUNET_free (routeList); 342 GNUNET_free (routeList);
335 return result; 343 return result;
336} 344}
@@ -344,7 +352,8 @@ parse_ipv6_specification (const char *routeListX)
344 * @return GNUNET_NO if the IP is not in the list, GNUNET_YES if it it is 352 * @return GNUNET_NO if the IP is not in the list, GNUNET_YES if it it is
345 */ 353 */
346static int 354static int
347check_ipv4_listed (const struct IPv4NetworkSet *list, const struct in_addr *add) 355check_ipv4_listed (const struct IPv4NetworkSet *list,
356 const struct in_addr *add)
348{ 357{
349 int i; 358 int i;
350 359
@@ -353,12 +362,12 @@ check_ipv4_listed (const struct IPv4NetworkSet *list, const struct in_addr *add)
353 return GNUNET_NO; 362 return GNUNET_NO;
354 363
355 while ((list[i].network.s_addr != 0) || (list[i].netmask.s_addr != 0)) 364 while ((list[i].network.s_addr != 0) || (list[i].netmask.s_addr != 0))
356 { 365 {
357 if ((add->s_addr & list[i].netmask.s_addr) == 366 if ((add->s_addr & list[i].netmask.s_addr) ==
358 (list[i].network.s_addr & list[i].netmask.s_addr)) 367 (list[i].network.s_addr & list[i].netmask.s_addr))
359 return GNUNET_YES; 368 return GNUNET_YES;
360 i++; 369 i++;
361 } 370 }
362 return GNUNET_NO; 371 return GNUNET_NO;
363} 372}
364 373
@@ -370,7 +379,8 @@ check_ipv4_listed (const struct IPv4NetworkSet *list, const struct in_addr *add)
370 * @return GNUNET_NO if the IP is not in the list, GNUNET_YES if it it is 379 * @return GNUNET_NO if the IP is not in the list, GNUNET_YES if it it is
371 */ 380 */
372static int 381static int
373check_ipv6_listed (const struct IPv6NetworkSet *list, const struct in6_addr *ip) 382check_ipv6_listed (const struct IPv6NetworkSet *list,
383 const struct in6_addr *ip)
374{ 384{
375 unsigned int i; 385 unsigned int i;
376 unsigned int j; 386 unsigned int j;
@@ -383,16 +393,16 @@ check_ipv6_listed (const struct IPv6NetworkSet *list, const struct in6_addr *ip)
383 i = 0; 393 i = 0;
384NEXT: 394NEXT:
385 while (memcmp (&zero, &list[i].network, sizeof (struct in6_addr)) != 0) 395 while (memcmp (&zero, &list[i].network, sizeof (struct in6_addr)) != 0)
386 { 396 {
387 for (j = 0; j < sizeof (struct in6_addr) / sizeof (int); j++) 397 for (j = 0; j < sizeof (struct in6_addr) / sizeof (int); j++)
388 if (((((int *) ip)[j] & ((int *) &list[i].netmask)[j])) != 398 if (((((int *) ip)[j] & ((int *) &list[i].netmask)[j])) !=
389 (((int *) &list[i].network)[j] & ((int *) &list[i].netmask)[j])) 399 (((int *) &list[i].network)[j] & ((int *) &list[i].netmask)[j]))
390 { 400 {
391 i++; 401 i++;
392 goto NEXT; 402 goto NEXT;
393 } 403 }
394 return GNUNET_YES; 404 return GNUNET_YES;
395 } 405 }
396 return GNUNET_NO; 406 return GNUNET_NO;
397} 407}
398 408
@@ -526,10 +536,10 @@ write_test (void *cls, size_t size, void *buf)
526 struct GNUNET_MessageHeader *msg; 536 struct GNUNET_MessageHeader *msg;
527 537
528 if (size < sizeof (struct GNUNET_MessageHeader)) 538 if (size < sizeof (struct GNUNET_MessageHeader))
529 { 539 {
530 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 540 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
531 return 0; /* client disconnected */ 541 return 0; /* client disconnected */
532 } 542 }
533 msg = (struct GNUNET_MessageHeader *) buf; 543 msg = (struct GNUNET_MessageHeader *) buf;
534 msg->type = htons (GNUNET_MESSAGE_TYPE_TEST); 544 msg->type = htons (GNUNET_MESSAGE_TYPE_TEST);
535 msg->size = htons (sizeof (struct GNUNET_MessageHeader)); 545 msg->size = htons (sizeof (struct GNUNET_MessageHeader));
@@ -546,14 +556,15 @@ write_test (void *cls, size_t size, void *buf)
546 */ 556 */
547static void 557static void
548handle_test (void *cls, struct GNUNET_SERVER_Client *client, 558handle_test (void *cls, struct GNUNET_SERVER_Client *client,
549 const struct GNUNET_MessageHeader *message) 559 const struct GNUNET_MessageHeader *message)
550{ 560{
551 /* simply bounce message back to acknowledge */ 561 /* simply bounce message back to acknowledge */
552 if (NULL == 562 if (NULL ==
553 GNUNET_SERVER_notify_transmit_ready (client, 563 GNUNET_SERVER_notify_transmit_ready (client,
554 sizeof (struct GNUNET_MessageHeader), 564 sizeof (struct
555 GNUNET_TIME_UNIT_FOREVER_REL, 565 GNUNET_MessageHeader),
556 &write_test, client)) 566 GNUNET_TIME_UNIT_FOREVER_REL,
567 &write_test, client))
557 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 568 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
558} 569}
559 570
@@ -586,7 +597,7 @@ static const struct GNUNET_SERVER_MessageHandler defhandlers[] = {
586 */ 597 */
587static int 598static int
588check_access (void *cls, const struct GNUNET_CONNECTION_Credentials *uc, 599check_access (void *cls, const struct GNUNET_CONNECTION_Credentials *uc,
589 const struct sockaddr *addr, socklen_t addrlen) 600 const struct sockaddr *addr, socklen_t addrlen)
590{ 601{
591 struct GNUNET_SERVICE_Context *sctx = cls; 602 struct GNUNET_SERVICE_Context *sctx = cls;
592 const struct sockaddr_in *i4; 603 const struct sockaddr_in *i4;
@@ -594,51 +605,51 @@ check_access (void *cls, const struct GNUNET_CONNECTION_Credentials *uc,
594 int ret; 605 int ret;
595 606
596 switch (addr->sa_family) 607 switch (addr->sa_family)
597 { 608 {
598 case AF_INET: 609 case AF_INET:
599 GNUNET_assert (addrlen == sizeof (struct sockaddr_in)); 610 GNUNET_assert (addrlen == sizeof (struct sockaddr_in));
600 i4 = (const struct sockaddr_in *) addr; 611 i4 = (const struct sockaddr_in *) addr;
601 ret = ((sctx->v4_allowed == NULL) || 612 ret = ((sctx->v4_allowed == NULL) ||
602 (check_ipv4_listed (sctx->v4_allowed, &i4->sin_addr))) && 613 (check_ipv4_listed (sctx->v4_allowed, &i4->sin_addr))) &&
603 ((sctx->v4_denied == NULL) || 614 ((sctx->v4_denied == NULL) ||
604 (!check_ipv4_listed (sctx->v4_denied, &i4->sin_addr))); 615 (!check_ipv4_listed (sctx->v4_denied, &i4->sin_addr)));
605 break; 616 break;
606 case AF_INET6: 617 case AF_INET6:
607 GNUNET_assert (addrlen == sizeof (struct sockaddr_in6)); 618 GNUNET_assert (addrlen == sizeof (struct sockaddr_in6));
608 i6 = (const struct sockaddr_in6 *) addr; 619 i6 = (const struct sockaddr_in6 *) addr;
609 ret = ((sctx->v6_allowed == NULL) || 620 ret = ((sctx->v6_allowed == NULL) ||
610 (check_ipv6_listed (sctx->v6_allowed, &i6->sin6_addr))) && 621 (check_ipv6_listed (sctx->v6_allowed, &i6->sin6_addr))) &&
611 ((sctx->v6_denied == NULL) || 622 ((sctx->v6_denied == NULL) ||
612 (!check_ipv6_listed (sctx->v6_denied, &i6->sin6_addr))); 623 (!check_ipv6_listed (sctx->v6_denied, &i6->sin6_addr)));
613 break; 624 break;
614#ifndef WINDOWS 625#ifndef WINDOWS
615 case AF_UNIX: 626 case AF_UNIX:
616 ret = GNUNET_OK; /* always OK for now */ 627 ret = GNUNET_OK; /* always OK for now */
617 if ((sctx->match_uid == GNUNET_YES) || (sctx->match_gid == GNUNET_YES)) 628 if ((sctx->match_uid == GNUNET_YES) || (sctx->match_gid == GNUNET_YES))
618 ret = GNUNET_NO; 629 ret = GNUNET_NO;
619 if ((uc != NULL) && 630 if ((uc != NULL) &&
620 ((sctx->match_uid != GNUNET_YES) || (uc->uid == geteuid ()) || 631 ((sctx->match_uid != GNUNET_YES) || (uc->uid == geteuid ()) ||
621 (uc->uid == getuid ())) && ((sctx->match_gid != GNUNET_YES) || 632 (uc->uid == getuid ())) && ((sctx->match_gid != GNUNET_YES) ||
622 (uc->gid == getegid ()) || 633 (uc->gid == getegid ()) ||
623 (uc->gid == getgid ()))) 634 (uc->gid == getgid ())))
624 ret = GNUNET_YES; 635 ret = GNUNET_YES;
625 else 636 else
626 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 637 LOG (GNUNET_ERROR_TYPE_WARNING,
627 _("Access denied to UID %d / GID %d\n"), 638 _("Access denied to UID %d / GID %d\n"),
628 (uc == NULL) ? -1 : uc->uid, (uc == NULL) ? -1 : uc->gid); 639 (uc == NULL) ? -1 : uc->uid, (uc == NULL) ? -1 : uc->gid);
629 break; 640 break;
630#endif 641#endif
631 default: 642 default:
632 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Unknown address family %d\n"), 643 LOG (GNUNET_ERROR_TYPE_WARNING, _("Unknown address family %d\n"),
633 addr->sa_family); 644 addr->sa_family);
634 return GNUNET_SYSERR; 645 return GNUNET_SYSERR;
635 } 646 }
636 if (ret != GNUNET_OK) 647 if (ret != GNUNET_OK)
637 { 648 {
638 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 649 LOG (GNUNET_ERROR_TYPE_WARNING,
639 _("Access from `%s' denied to service `%s'\n"), 650 _("Access from `%s' denied to service `%s'\n"),
640 GNUNET_a2s (addr, addrlen), sctx->serviceName); 651 GNUNET_a2s (addr, addrlen), sctx->serviceName);
641 } 652 }
642 return ret; 653 return ret;
643} 654}
644 655
@@ -655,7 +666,7 @@ get_pid_file_name (struct GNUNET_SERVICE_Context *sctx)
655 666
656 if (GNUNET_OK != 667 if (GNUNET_OK !=
657 GNUNET_CONFIGURATION_get_value_filename (sctx->cfg, sctx->serviceName, 668 GNUNET_CONFIGURATION_get_value_filename (sctx->cfg, sctx->serviceName,
658 "PIDFILE", &pif)) 669 "PIDFILE", &pif))
659 return NULL; 670 return NULL;
660 return pif; 671 return pif;
661} 672}
@@ -665,26 +676,26 @@ get_pid_file_name (struct GNUNET_SERVICE_Context *sctx)
665 * Parse an IPv4 access control list. 676 * Parse an IPv4 access control list.
666 */ 677 */
667static int 678static int
668process_acl4 (struct IPv4NetworkSet **ret, struct GNUNET_SERVICE_Context *sctx, 679process_acl4 (struct IPv4NetworkSet **ret,
669 const char *option) 680 struct GNUNET_SERVICE_Context *sctx, const char *option)
670{ 681{
671 char *opt; 682 char *opt;
672 683
673 if (!GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->serviceName, option)) 684 if (!GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->serviceName, option))
674 return GNUNET_OK; 685 return GNUNET_OK;
675 GNUNET_break (GNUNET_OK == 686 GNUNET_break (GNUNET_OK ==
676 GNUNET_CONFIGURATION_get_value_string (sctx->cfg, 687 GNUNET_CONFIGURATION_get_value_string (sctx->cfg,
677 sctx->serviceName, 688 sctx->serviceName,
678 option, &opt)); 689 option, &opt));
679 if (NULL == (*ret = parse_ipv4_specification (opt))) 690 if (NULL == (*ret = parse_ipv4_specification (opt)))
680 { 691 {
681 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 692 LOG (GNUNET_ERROR_TYPE_WARNING,
682 _ 693 _
683 ("Could not parse IPv4 network specification `%s' for `%s:%s'\n"), 694 ("Could not parse IPv4 network specification `%s' for `%s:%s'\n"),
684 opt, sctx->serviceName, option); 695 opt, sctx->serviceName, option);
685 GNUNET_free (opt); 696 GNUNET_free (opt);
686 return GNUNET_SYSERR; 697 return GNUNET_SYSERR;
687 } 698 }
688 GNUNET_free (opt); 699 GNUNET_free (opt);
689 return GNUNET_OK; 700 return GNUNET_OK;
690} 701}
@@ -694,26 +705,26 @@ process_acl4 (struct IPv4NetworkSet **ret, struct GNUNET_SERVICE_Context *sctx,
694 * Parse an IPv4 access control list. 705 * Parse an IPv4 access control list.
695 */ 706 */
696static int 707static int
697process_acl6 (struct IPv6NetworkSet **ret, struct GNUNET_SERVICE_Context *sctx, 708process_acl6 (struct IPv6NetworkSet **ret,
698 const char *option) 709 struct GNUNET_SERVICE_Context *sctx, const char *option)
699{ 710{
700 char *opt; 711 char *opt;
701 712
702 if (!GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->serviceName, option)) 713 if (!GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->serviceName, option))
703 return GNUNET_OK; 714 return GNUNET_OK;
704 GNUNET_break (GNUNET_OK == 715 GNUNET_break (GNUNET_OK ==
705 GNUNET_CONFIGURATION_get_value_string (sctx->cfg, 716 GNUNET_CONFIGURATION_get_value_string (sctx->cfg,
706 sctx->serviceName, 717 sctx->serviceName,
707 option, &opt)); 718 option, &opt));
708 if (NULL == (*ret = parse_ipv6_specification (opt))) 719 if (NULL == (*ret = parse_ipv6_specification (opt)))
709 { 720 {
710 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 721 LOG (GNUNET_ERROR_TYPE_WARNING,
711 _ 722 _
712 ("Could not parse IPv6 network specification `%s' for `%s:%s'\n"), 723 ("Could not parse IPv6 network specification `%s' for `%s:%s'\n"),
713 opt, sctx->serviceName, option); 724 opt, sctx->serviceName, option);
714 GNUNET_free (opt); 725 GNUNET_free (opt);
715 return GNUNET_SYSERR; 726 return GNUNET_SYSERR;
716 } 727 }
717 GNUNET_free (opt); 728 GNUNET_free (opt);
718 return GNUNET_OK; 729 return GNUNET_OK;
719} 730}
@@ -728,7 +739,7 @@ process_acl6 (struct IPv6NetworkSet **ret, struct GNUNET_SERVICE_Context *sctx,
728 */ 739 */
729static void 740static void
730add_unixpath (struct sockaddr **saddrs, socklen_t * saddrlens, 741add_unixpath (struct sockaddr **saddrs, socklen_t * saddrlens,
731 const char *unixpath) 742 const char *unixpath)
732{ 743{
733#ifdef AF_UNIX 744#ifdef AF_UNIX
734 struct sockaddr_un *un; 745 struct sockaddr_un *un;
@@ -780,9 +791,9 @@ add_unixpath (struct sockaddr **saddrs, socklen_t * saddrlens,
780 */ 791 */
781int 792int
782GNUNET_SERVICE_get_server_addresses (const char *serviceName, 793GNUNET_SERVICE_get_server_addresses (const char *serviceName,
783 const struct GNUNET_CONFIGURATION_Handle 794 const struct GNUNET_CONFIGURATION_Handle
784 *cfg, struct sockaddr ***addrs, 795 *cfg, struct sockaddr ***addrs,
785 socklen_t ** addr_lens) 796 socklen_t ** addr_lens)
786{ 797{
787 int disablev6; 798 int disablev6;
788 struct GNUNET_NETWORK_Handle *desc; 799 struct GNUNET_NETWORK_Handle *desc;
@@ -803,62 +814,64 @@ GNUNET_SERVICE_get_server_addresses (const char *serviceName,
803 *addr_lens = NULL; 814 *addr_lens = NULL;
804 desc = NULL; 815 desc = NULL;
805 if (GNUNET_CONFIGURATION_have_value (cfg, serviceName, "DISABLEV6")) 816 if (GNUNET_CONFIGURATION_have_value (cfg, serviceName, "DISABLEV6"))
806 { 817 {
807 if (GNUNET_SYSERR == 818 if (GNUNET_SYSERR ==
808 (disablev6 = 819 (disablev6 =
809 GNUNET_CONFIGURATION_get_value_yesno (cfg, serviceName, "DISABLEV6"))) 820 GNUNET_CONFIGURATION_get_value_yesno (cfg, serviceName,
810 return GNUNET_SYSERR; 821 "DISABLEV6")))
811 } 822 return GNUNET_SYSERR;
823 }
812 else 824 else
813 disablev6 = GNUNET_NO; 825 disablev6 = GNUNET_NO;
814 826
815 if (!disablev6) 827 if (!disablev6)
816 {
817 /* probe IPv6 support */
818 desc = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0);
819 if (NULL == desc)
820 { 828 {
821 if ((errno == ENOBUFS) || (errno == ENOMEM) || (errno == ENFILE) || 829 /* probe IPv6 support */
822 (errno == EACCES)) 830 desc = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0);
823 { 831 if (NULL == desc)
824 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "socket"); 832 {
825 return GNUNET_SYSERR; 833 if ((errno == ENOBUFS) || (errno == ENOMEM) || (errno == ENFILE) ||
826 } 834 (errno == EACCES))
827 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 835 {
828 _ 836 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "socket");
829 ("Disabling IPv6 support for service `%s', failed to create IPv6 socket: %s\n"), 837 return GNUNET_SYSERR;
830 serviceName, STRERROR (errno)); 838 }
831 disablev6 = GNUNET_YES; 839 LOG (GNUNET_ERROR_TYPE_INFO,
832 } 840 _
833 else 841 ("Disabling IPv6 support for service `%s', failed to create IPv6 socket: %s\n"),
834 { 842 serviceName, STRERROR (errno));
835 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (desc)); 843 disablev6 = GNUNET_YES;
836 desc = NULL; 844 }
845 else
846 {
847 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (desc));
848 desc = NULL;
849 }
837 } 850 }
838 }
839 851
840 port = 0; 852 port = 0;
841 if (GNUNET_CONFIGURATION_have_value (cfg, serviceName, "PORT")) 853 if (GNUNET_CONFIGURATION_have_value (cfg, serviceName, "PORT"))
842 {
843 GNUNET_break (GNUNET_OK ==
844 GNUNET_CONFIGURATION_get_value_number (cfg, serviceName,
845 "PORT", &port));
846 if (port > 65535)
847 { 854 {
848 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 855 GNUNET_break (GNUNET_OK ==
849 _ 856 GNUNET_CONFIGURATION_get_value_number (cfg, serviceName,
850 ("Require valid port number for service `%s' in configuration!\n"), 857 "PORT", &port));
851 serviceName); 858 if (port > 65535)
852 return GNUNET_SYSERR; 859 {
860 LOG (GNUNET_ERROR_TYPE_ERROR,
861 _
862 ("Require valid port number for service `%s' in configuration!\n"),
863 serviceName);
864 return GNUNET_SYSERR;
865 }
853 } 866 }
854 }
855 867
856 if (GNUNET_CONFIGURATION_have_value (cfg, serviceName, "BINDTO")) 868 if (GNUNET_CONFIGURATION_have_value (cfg, serviceName, "BINDTO"))
857 { 869 {
858 GNUNET_break (GNUNET_OK == 870 GNUNET_break (GNUNET_OK ==
859 GNUNET_CONFIGURATION_get_value_string (cfg, serviceName, 871 GNUNET_CONFIGURATION_get_value_string (cfg, serviceName,
860 "BINDTO", &hostname)); 872 "BINDTO",
861 } 873 &hostname));
874 }
862 else 875 else
863 hostname = NULL; 876 hostname = NULL;
864 877
@@ -868,211 +881,211 @@ GNUNET_SERVICE_get_server_addresses (const char *serviceName,
868 GNUNET_CONFIGURATION_have_value (cfg, serviceName, "UNIXPATH")) && 881 GNUNET_CONFIGURATION_have_value (cfg, serviceName, "UNIXPATH")) &&
869 (GNUNET_OK == 882 (GNUNET_OK ==
870 GNUNET_CONFIGURATION_get_value_string (cfg, serviceName, "UNIXPATH", 883 GNUNET_CONFIGURATION_get_value_string (cfg, serviceName, "UNIXPATH",
871 &unixpath)) && 884 &unixpath)) &&
872 (0 < strlen (unixpath))) 885 (0 < strlen (unixpath)))
873 {
874 /* probe UNIX support */
875 struct sockaddr_un s_un;
876
877 if (strlen (unixpath) >= sizeof (s_un.sun_path))
878 {
879 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
880 _("UNIXPATH `%s' too long, maximum length is %llu\n"),
881 unixpath, sizeof (s_un.sun_path));
882 GNUNET_free_non_null (hostname);
883 GNUNET_free (unixpath);
884 return GNUNET_SYSERR;
885 }
886
887 desc = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0);
888 if (NULL == desc)
889 { 886 {
890 if ((errno == ENOBUFS) || (errno == ENOMEM) || (errno == ENFILE) || 887 /* probe UNIX support */
891 (errno == EACCES)) 888 struct sockaddr_un s_un;
892 { 889
893 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "socket"); 890 if (strlen (unixpath) >= sizeof (s_un.sun_path))
894 GNUNET_free_non_null (hostname); 891 {
895 GNUNET_free (unixpath); 892 LOG (GNUNET_ERROR_TYPE_WARNING,
896 return GNUNET_SYSERR; 893 _("UNIXPATH `%s' too long, maximum length is %llu\n"),
897 } 894 unixpath, sizeof (s_un.sun_path));
898 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 895 GNUNET_free_non_null (hostname);
899 _ 896 GNUNET_free (unixpath);
900 ("Disabling UNIX domain socket support for service `%s', failed to create UNIX domain socket: %s\n"), 897 return GNUNET_SYSERR;
901 serviceName, STRERROR (errno)); 898 }
902 GNUNET_free (unixpath); 899
903 unixpath = NULL; 900 desc = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0);
904 } 901 if (NULL == desc)
905 else 902 {
906 { 903 if ((errno == ENOBUFS) || (errno == ENOMEM) || (errno == ENFILE) ||
907 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (desc)); 904 (errno == EACCES))
908 desc = NULL; 905 {
906 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "socket");
907 GNUNET_free_non_null (hostname);
908 GNUNET_free (unixpath);
909 return GNUNET_SYSERR;
910 }
911 LOG (GNUNET_ERROR_TYPE_INFO,
912 _
913 ("Disabling UNIX domain socket support for service `%s', failed to create UNIX domain socket: %s\n"),
914 serviceName, STRERROR (errno));
915 GNUNET_free (unixpath);
916 unixpath = NULL;
917 }
918 else
919 {
920 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (desc));
921 desc = NULL;
922 }
909 } 923 }
910 }
911#endif 924#endif
912 925
913 if ((port == 0) && (unixpath == NULL)) 926 if ((port == 0) && (unixpath == NULL))
914 {
915 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
916 _
917 ("Have neither PORT nor UNIXPATH for service `%s', but one is required\n"),
918 serviceName);
919 GNUNET_free_non_null (hostname);
920 return GNUNET_SYSERR;
921 }
922 if (port == 0)
923 {
924 saddrs = GNUNET_malloc (2 * sizeof (struct sockaddr *));
925 saddrlens = GNUNET_malloc (2 * sizeof (socklen_t));
926 add_unixpath (saddrs, saddrlens, unixpath);
927 GNUNET_free_non_null (unixpath);
928 GNUNET_free_non_null (hostname);
929 *addrs = saddrs;
930 *addr_lens = saddrlens;
931 return 1;
932 }
933
934 if (hostname != NULL)
935 {
936#if DEBUG_SERVICE
937 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
938 "Resolving `%s' since that is where `%s' will bind to.\n",
939 hostname, serviceName);
940#endif
941 memset (&hints, 0, sizeof (struct addrinfo));
942 if (disablev6)
943 hints.ai_family = AF_INET;
944 if ((0 != (ret = getaddrinfo (hostname, NULL, &hints, &res))) ||
945 (res == NULL))
946 {
947 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to resolve `%s': %s\n"),
948 hostname, gai_strerror (ret));
949 GNUNET_free (hostname);
950 GNUNET_free_non_null (unixpath);
951 return GNUNET_SYSERR;
952 }
953 next = res;
954 i = 0;
955 while (NULL != (pos = next))
956 {
957 next = pos->ai_next;
958 if ((disablev6) && (pos->ai_family == AF_INET6))
959 continue;
960 i++;
961 }
962 if (0 == i)
963 { 927 {
964 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 928 LOG (GNUNET_ERROR_TYPE_ERROR,
965 _("Failed to find %saddress for `%s'.\n"), 929 _
966 disablev6 ? "IPv4 " : "", hostname); 930 ("Have neither PORT nor UNIXPATH for service `%s', but one is required\n"),
967 freeaddrinfo (res); 931 serviceName);
968 GNUNET_free (hostname); 932 GNUNET_free_non_null (hostname);
969 GNUNET_free_non_null (unixpath);
970 return GNUNET_SYSERR; 933 return GNUNET_SYSERR;
971 } 934 }
972 resi = i; 935 if (port == 0)
973 if (NULL != unixpath)
974 resi++;
975 saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *));
976 saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t));
977 i = 0;
978 if (NULL != unixpath)
979 { 936 {
937 saddrs = GNUNET_malloc (2 * sizeof (struct sockaddr *));
938 saddrlens = GNUNET_malloc (2 * sizeof (socklen_t));
980 add_unixpath (saddrs, saddrlens, unixpath); 939 add_unixpath (saddrs, saddrlens, unixpath);
981 i++; 940 GNUNET_free_non_null (unixpath);
941 GNUNET_free_non_null (hostname);
942 *addrs = saddrs;
943 *addr_lens = saddrlens;
944 return 1;
982 } 945 }
983 next = res; 946
984 while (NULL != (pos = next)) 947 if (hostname != NULL)
985 { 948 {
986 next = pos->ai_next;
987 if ((disablev6) && (pos->ai_family == AF_INET6))
988 continue;
989 if ((pos->ai_protocol != IPPROTO_TCP) && (pos->ai_protocol != 0))
990 continue; /* not TCP */
991 if ((pos->ai_socktype != SOCK_STREAM) && (pos->ai_socktype != 0))
992 continue; /* huh? */
993#if DEBUG_SERVICE 949#if DEBUG_SERVICE
994 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Service `%s' will bind to `%s'\n", 950 LOG (GNUNET_ERROR_TYPE_DEBUG,
995 serviceName, GNUNET_a2s (pos->ai_addr, pos->ai_addrlen)); 951 "Resolving `%s' since that is where `%s' will bind to.\n",
952 hostname, serviceName);
996#endif 953#endif
997 if (pos->ai_family == AF_INET) 954 memset (&hints, 0, sizeof (struct addrinfo));
998 { 955 if (disablev6)
999 GNUNET_assert (pos->ai_addrlen == sizeof (struct sockaddr_in)); 956 hints.ai_family = AF_INET;
1000 saddrlens[i] = pos->ai_addrlen; 957 if ((0 != (ret = getaddrinfo (hostname, NULL, &hints, &res))) ||
1001 saddrs[i] = GNUNET_malloc (saddrlens[i]); 958 (res == NULL))
1002 memcpy (saddrs[i], pos->ai_addr, saddrlens[i]); 959 {
1003 ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port); 960 LOG (GNUNET_ERROR_TYPE_ERROR, _("Failed to resolve `%s': %s\n"),
1004 } 961 hostname, gai_strerror (ret));
1005 else 962 GNUNET_free (hostname);
1006 { 963 GNUNET_free_non_null (unixpath);
1007 GNUNET_assert (pos->ai_family == AF_INET6); 964 return GNUNET_SYSERR;
1008 GNUNET_assert (pos->ai_addrlen == sizeof (struct sockaddr_in6)); 965 }
1009 saddrlens[i] = pos->ai_addrlen; 966 next = res;
1010 saddrs[i] = GNUNET_malloc (saddrlens[i]);
1011 memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
1012 ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
1013 }
1014 i++;
1015 }
1016 GNUNET_free (hostname);
1017 freeaddrinfo (res);
1018 resi = i;
1019 }
1020 else
1021 {
1022 /* will bind against everything, just set port */
1023 if (disablev6)
1024 {
1025 /* V4-only */
1026 resi = 1;
1027 if (NULL != unixpath)
1028 resi++;
1029 i = 0; 967 i = 0;
968 while (NULL != (pos = next))
969 {
970 next = pos->ai_next;
971 if ((disablev6) && (pos->ai_family == AF_INET6))
972 continue;
973 i++;
974 }
975 if (0 == i)
976 {
977 LOG (GNUNET_ERROR_TYPE_ERROR,
978 _("Failed to find %saddress for `%s'.\n"),
979 disablev6 ? "IPv4 " : "", hostname);
980 freeaddrinfo (res);
981 GNUNET_free (hostname);
982 GNUNET_free_non_null (unixpath);
983 return GNUNET_SYSERR;
984 }
985 resi = i;
986 if (NULL != unixpath)
987 resi++;
1030 saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *)); 988 saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *));
1031 saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t)); 989 saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t));
990 i = 0;
1032 if (NULL != unixpath) 991 if (NULL != unixpath)
1033 { 992 {
1034 add_unixpath (saddrs, saddrlens, unixpath); 993 add_unixpath (saddrs, saddrlens, unixpath);
1035 i++; 994 i++;
1036 } 995 }
1037 saddrlens[i] = sizeof (struct sockaddr_in); 996 next = res;
1038 saddrs[i] = GNUNET_malloc (saddrlens[i]); 997 while (NULL != (pos = next))
1039#if HAVE_SOCKADDR_IN_SIN_LEN 998 {
1040 ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[i]; 999 next = pos->ai_next;
1000 if ((disablev6) && (pos->ai_family == AF_INET6))
1001 continue;
1002 if ((pos->ai_protocol != IPPROTO_TCP) && (pos->ai_protocol != 0))
1003 continue; /* not TCP */
1004 if ((pos->ai_socktype != SOCK_STREAM) && (pos->ai_socktype != 0))
1005 continue; /* huh? */
1006#if DEBUG_SERVICE
1007 LOG (GNUNET_ERROR_TYPE_DEBUG, "Service `%s' will bind to `%s'\n",
1008 serviceName, GNUNET_a2s (pos->ai_addr, pos->ai_addrlen));
1041#endif 1009#endif
1042 ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET; 1010 if (pos->ai_family == AF_INET)
1043 ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port); 1011 {
1012 GNUNET_assert (pos->ai_addrlen == sizeof (struct sockaddr_in));
1013 saddrlens[i] = pos->ai_addrlen;
1014 saddrs[i] = GNUNET_malloc (saddrlens[i]);
1015 memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
1016 ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
1017 }
1018 else
1019 {
1020 GNUNET_assert (pos->ai_family == AF_INET6);
1021 GNUNET_assert (pos->ai_addrlen == sizeof (struct sockaddr_in6));
1022 saddrlens[i] = pos->ai_addrlen;
1023 saddrs[i] = GNUNET_malloc (saddrlens[i]);
1024 memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
1025 ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
1026 }
1027 i++;
1028 }
1029 GNUNET_free (hostname);
1030 freeaddrinfo (res);
1031 resi = i;
1044 } 1032 }
1045 else 1033 else
1046 { 1034 {
1047 /* dual stack */ 1035 /* will bind against everything, just set port */
1048 resi = 2; 1036 if (disablev6)
1049 if (NULL != unixpath) 1037 {
1050 resi++; 1038 /* V4-only */
1051 saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *)); 1039 resi = 1;
1052 saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t)); 1040 if (NULL != unixpath)
1053 i = 0; 1041 resi++;
1054 if (NULL != unixpath) 1042 i = 0;
1055 { 1043 saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *));
1056 add_unixpath (saddrs, saddrlens, unixpath); 1044 saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t));
1057 i++; 1045 if (NULL != unixpath)
1058 } 1046 {
1059 saddrlens[i] = sizeof (struct sockaddr_in6); 1047 add_unixpath (saddrs, saddrlens, unixpath);
1060 saddrs[i] = GNUNET_malloc (saddrlens[i]); 1048 i++;
1049 }
1050 saddrlens[i] = sizeof (struct sockaddr_in);
1051 saddrs[i] = GNUNET_malloc (saddrlens[i]);
1061#if HAVE_SOCKADDR_IN_SIN_LEN 1052#if HAVE_SOCKADDR_IN_SIN_LEN
1062 ((struct sockaddr_in6 *) saddrs[i])->sin6_len = saddrlens[0]; 1053 ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[i];
1063#endif 1054#endif
1064 ((struct sockaddr_in6 *) saddrs[i])->sin6_family = AF_INET6; 1055 ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
1065 ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port); 1056 ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
1066 i++; 1057 }
1067 saddrlens[i] = sizeof (struct sockaddr_in); 1058 else
1068 saddrs[i] = GNUNET_malloc (saddrlens[i]); 1059 {
1060 /* dual stack */
1061 resi = 2;
1062 if (NULL != unixpath)
1063 resi++;
1064 saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *));
1065 saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t));
1066 i = 0;
1067 if (NULL != unixpath)
1068 {
1069 add_unixpath (saddrs, saddrlens, unixpath);
1070 i++;
1071 }
1072 saddrlens[i] = sizeof (struct sockaddr_in6);
1073 saddrs[i] = GNUNET_malloc (saddrlens[i]);
1069#if HAVE_SOCKADDR_IN_SIN_LEN 1074#if HAVE_SOCKADDR_IN_SIN_LEN
1070 ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[1]; 1075 ((struct sockaddr_in6 *) saddrs[i])->sin6_len = saddrlens[0];
1071#endif 1076#endif
1072 ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET; 1077 ((struct sockaddr_in6 *) saddrs[i])->sin6_family = AF_INET6;
1073 ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port); 1078 ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
1079 i++;
1080 saddrlens[i] = sizeof (struct sockaddr_in);
1081 saddrs[i] = GNUNET_malloc (saddrlens[i]);
1082#if HAVE_SOCKADDR_IN_SIN_LEN
1083 ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[1];
1084#endif
1085 ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
1086 ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
1087 }
1074 } 1088 }
1075 }
1076 GNUNET_free_non_null (unixpath); 1089 GNUNET_free_non_null (unixpath);
1077 *addrs = saddrs; 1090 *addrs = saddrs;
1078 *addr_lens = saddrlens; 1091 *addr_lens = saddrlens;
@@ -1111,36 +1124,37 @@ setup_service (struct GNUNET_SERVICE_Context *sctx)
1111 int flags; 1124 int flags;
1112#endif 1125#endif
1113 1126
1114 if (GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->serviceName, "TIMEOUT")) 1127 if (GNUNET_CONFIGURATION_have_value
1115 { 1128 (sctx->cfg, sctx->serviceName, "TIMEOUT"))
1116 if (GNUNET_OK !=
1117 GNUNET_CONFIGURATION_get_value_time (sctx->cfg, sctx->serviceName,
1118 "TIMEOUT", &idleout))
1119 { 1129 {
1120 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1130 if (GNUNET_OK !=
1121 _("Specified value for `%s' of service `%s' is invalid\n"), 1131 GNUNET_CONFIGURATION_get_value_time (sctx->cfg, sctx->serviceName,
1122 "TIMEOUT", sctx->serviceName); 1132 "TIMEOUT", &idleout))
1123 return GNUNET_SYSERR; 1133 {
1134 LOG (GNUNET_ERROR_TYPE_ERROR,
1135 _("Specified value for `%s' of service `%s' is invalid\n"),
1136 "TIMEOUT", sctx->serviceName);
1137 return GNUNET_SYSERR;
1138 }
1139 sctx->timeout = idleout;
1124 } 1140 }
1125 sctx->timeout = idleout;
1126 }
1127 else 1141 else
1128 sctx->timeout = GNUNET_TIME_UNIT_FOREVER_REL; 1142 sctx->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
1129 1143
1130 if (GNUNET_CONFIGURATION_have_value 1144 if (GNUNET_CONFIGURATION_have_value
1131 (sctx->cfg, sctx->serviceName, "TOLERANT")) 1145 (sctx->cfg, sctx->serviceName, "TOLERANT"))
1132 {
1133 if (GNUNET_SYSERR ==
1134 (tolerant =
1135 GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg, sctx->serviceName,
1136 "TOLERANT")))
1137 { 1146 {
1138 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1147 if (GNUNET_SYSERR ==
1139 _("Specified value for `%s' of service `%s' is invalid\n"), 1148 (tolerant =
1140 "TOLERANT", sctx->serviceName); 1149 GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg, sctx->serviceName,
1141 return GNUNET_SYSERR; 1150 "TOLERANT")))
1151 {
1152 LOG (GNUNET_ERROR_TYPE_ERROR,
1153 _("Specified value for `%s' of service `%s' is invalid\n"),
1154 "TOLERANT", sctx->serviceName);
1155 return GNUNET_SYSERR;
1156 }
1142 } 1157 }
1143 }
1144 else 1158 else
1145 tolerant = GNUNET_NO; 1159 tolerant = GNUNET_NO;
1146 1160
@@ -1151,45 +1165,48 @@ setup_service (struct GNUNET_SERVICE_Context *sctx)
1151 (NULL != (nfds = getenv ("LISTEN_FDS"))) && 1165 (NULL != (nfds = getenv ("LISTEN_FDS"))) &&
1152 (1 == sscanf (nfds, "%u", &cnt)) && (cnt > 0) && (cnt < FD_SETSIZE) && 1166 (1 == sscanf (nfds, "%u", &cnt)) && (cnt > 0) && (cnt < FD_SETSIZE) &&
1153 (cnt + 4 < FD_SETSIZE)) 1167 (cnt + 4 < FD_SETSIZE))
1154 {
1155 sctx->lsocks =
1156 GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle *) * (cnt + 1));
1157 while (0 < cnt--)
1158 { 1168 {
1159 flags = fcntl (3 + cnt, F_GETFD); 1169 sctx->lsocks =
1160 if ((flags < 0) || (0 != (flags & FD_CLOEXEC)) || 1170 GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle *) * (cnt + 1));
1161 (NULL == 1171 while (0 < cnt--)
1162 (sctx->lsocks[cnt] = GNUNET_NETWORK_socket_box_native (3 + cnt)))) 1172 {
1163 { 1173 flags = fcntl (3 + cnt, F_GETFD);
1164 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1174 if ((flags < 0) || (0 != (flags & FD_CLOEXEC)) ||
1165 _ 1175 (NULL ==
1166 ("Could not access pre-bound socket %u, will try to bind myself\n"), 1176 (sctx->lsocks[cnt] =
1167 (unsigned int) 3 + cnt); 1177 GNUNET_NETWORK_socket_box_native (3 + cnt))))
1168 cnt++; 1178 {
1169 while (sctx->lsocks[cnt] != NULL) 1179 LOG (GNUNET_ERROR_TYPE_ERROR,
1170 GNUNET_break (0 == GNUNET_NETWORK_socket_close (sctx->lsocks[cnt++])); 1180 _
1171 GNUNET_free (sctx->lsocks); 1181 ("Could not access pre-bound socket %u, will try to bind myself\n"),
1172 sctx->lsocks = NULL; 1182 (unsigned int) 3 + cnt);
1173 break; 1183 cnt++;
1174 } 1184 while (sctx->lsocks[cnt] != NULL)
1185 GNUNET_break (0 ==
1186 GNUNET_NETWORK_socket_close (sctx->lsocks
1187 [cnt++]));
1188 GNUNET_free (sctx->lsocks);
1189 sctx->lsocks = NULL;
1190 break;
1191 }
1192 }
1193 unsetenv ("LISTEN_PID");
1194 unsetenv ("LISTEN_FDS");
1175 } 1195 }
1176 unsetenv ("LISTEN_PID");
1177 unsetenv ("LISTEN_FDS");
1178 }
1179#endif 1196#endif
1180 1197
1181 if ((sctx->lsocks == NULL) && 1198 if ((sctx->lsocks == NULL) &&
1182 (GNUNET_SYSERR == 1199 (GNUNET_SYSERR ==
1183 GNUNET_SERVICE_get_server_addresses (sctx->serviceName, sctx->cfg, 1200 GNUNET_SERVICE_get_server_addresses (sctx->serviceName, sctx->cfg,
1184 &sctx->addrs, &sctx->addrlens))) 1201 &sctx->addrs, &sctx->addrlens)))
1185 return GNUNET_SYSERR; 1202 return GNUNET_SYSERR;
1186 sctx->require_found = tolerant ? GNUNET_NO : GNUNET_YES; 1203 sctx->require_found = tolerant ? GNUNET_NO : GNUNET_YES;
1187 sctx->match_uid = 1204 sctx->match_uid =
1188 GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg, sctx->serviceName, 1205 GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg, sctx->serviceName,
1189 "UNIX_MATCH_UID"); 1206 "UNIX_MATCH_UID");
1190 sctx->match_gid = 1207 sctx->match_gid =
1191 GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg, sctx->serviceName, 1208 GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg, sctx->serviceName,
1192 "UNIX_MATCH_GID"); 1209 "UNIX_MATCH_GID");
1193 process_acl4 (&sctx->v4_denied, sctx, "REJECT_FROM"); 1210 process_acl4 (&sctx->v4_denied, sctx, "REJECT_FROM");
1194 process_acl4 (&sctx->v4_allowed, sctx, "ACCEPT_FROM"); 1211 process_acl4 (&sctx->v4_allowed, sctx, "ACCEPT_FROM");
1195 process_acl6 (&sctx->v6_denied, sctx, "REJECT_FROM6"); 1212 process_acl6 (&sctx->v6_denied, sctx, "REJECT_FROM6");
@@ -1211,7 +1228,7 @@ get_user_name (struct GNUNET_SERVICE_Context *sctx)
1211 1228
1212 if (GNUNET_OK != 1229 if (GNUNET_OK !=
1213 GNUNET_CONFIGURATION_get_value_filename (sctx->cfg, sctx->serviceName, 1230 GNUNET_CONFIGURATION_get_value_filename (sctx->cfg, sctx->serviceName,
1214 "USERNAME", &un)) 1231 "USERNAME", &un))
1215 return NULL; 1232 return NULL;
1216 return un; 1233 return un;
1217} 1234}
@@ -1229,7 +1246,7 @@ write_pid_file (struct GNUNET_SERVICE_Context *sctx, pid_t pid)
1229 int len; 1246 int len;
1230 1247
1231 if (NULL == (pif = get_pid_file_name (sctx))) 1248 if (NULL == (pif = get_pid_file_name (sctx)))
1232 return GNUNET_OK; /* no file desired */ 1249 return GNUNET_OK; /* no file desired */
1233 user = get_user_name (sctx); 1250 user = get_user_name (sctx);
1234 rdir = GNUNET_strdup (pif); 1251 rdir = GNUNET_strdup (pif);
1235 len = strlen (rdir); 1252 len = strlen (rdir);
@@ -1237,32 +1254,32 @@ write_pid_file (struct GNUNET_SERVICE_Context *sctx, pid_t pid)
1237 len--; 1254 len--;
1238 rdir[len] = '\0'; 1255 rdir[len] = '\0';
1239 if (0 != ACCESS (rdir, F_OK)) 1256 if (0 != ACCESS (rdir, F_OK))
1240 { 1257 {
1241 /* we get to create a directory -- and claim it 1258 /* we get to create a directory -- and claim it
1242 * as ours! */ 1259 * as ours! */
1243 GNUNET_DISK_directory_create (rdir); 1260 GNUNET_DISK_directory_create (rdir);
1244 if ((user != NULL) && (0 < strlen (user))) 1261 if ((user != NULL) && (0 < strlen (user)))
1245 GNUNET_DISK_file_change_owner (rdir, user); 1262 GNUNET_DISK_file_change_owner (rdir, user);
1246 } 1263 }
1247 if (0 != ACCESS (rdir, W_OK | X_OK)) 1264 if (0 != ACCESS (rdir, W_OK | X_OK))
1248 { 1265 {
1249 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "access", rdir); 1266 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "access", rdir);
1250 GNUNET_free (rdir); 1267 GNUNET_free (rdir);
1251 GNUNET_free_non_null (user); 1268 GNUNET_free_non_null (user);
1252 GNUNET_free (pif); 1269 GNUNET_free (pif);
1253 return GNUNET_SYSERR; 1270 return GNUNET_SYSERR;
1254 } 1271 }
1255 GNUNET_free (rdir); 1272 GNUNET_free (rdir);
1256 pidfd = FOPEN (pif, "w"); 1273 pidfd = FOPEN (pif, "w");
1257 if (pidfd == NULL) 1274 if (pidfd == NULL)
1258 { 1275 {
1259 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "fopen", pif); 1276 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "fopen", pif);
1260 GNUNET_free (pif); 1277 GNUNET_free (pif);
1261 GNUNET_free_non_null (user); 1278 GNUNET_free_non_null (user);
1262 return GNUNET_SYSERR; 1279 return GNUNET_SYSERR;
1263 } 1280 }
1264 if (0 > FPRINTF (pidfd, "%u", pid)) 1281 if (0 > FPRINTF (pidfd, "%u", pid))
1265 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "fprintf", pif); 1282 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fprintf", pif);
1266 GNUNET_break (0 == fclose (pidfd)); 1283 GNUNET_break (0 == fclose (pidfd));
1267 if ((user != NULL) && (0 < strlen (user))) 1284 if ((user != NULL) && (0 < strlen (user)))
1268 GNUNET_DISK_file_change_owner (pif, user); 1285 GNUNET_DISK_file_change_owner (pif, user);
@@ -1299,35 +1316,35 @@ service_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1299 GNUNET_RESOLVER_connect (sctx->cfg); 1316 GNUNET_RESOLVER_connect (sctx->cfg);
1300 if (sctx->lsocks != NULL) 1317 if (sctx->lsocks != NULL)
1301 sctx->server = 1318 sctx->server =
1302 GNUNET_SERVER_create_with_sockets (&check_access, sctx, sctx->lsocks, 1319 GNUNET_SERVER_create_with_sockets (&check_access, sctx, sctx->lsocks,
1303 sctx->timeout, sctx->require_found); 1320 sctx->timeout, sctx->require_found);
1304 else 1321 else
1305 sctx->server = 1322 sctx->server =
1306 GNUNET_SERVER_create (&check_access, sctx, sctx->addrs, sctx->addrlens, 1323 GNUNET_SERVER_create (&check_access, sctx, sctx->addrs, sctx->addrlens,
1307 sctx->timeout, sctx->require_found); 1324 sctx->timeout, sctx->require_found);
1308 if (sctx->server == NULL) 1325 if (sctx->server == NULL)
1309 {
1310 if (sctx->addrs != NULL)
1311 { 1326 {
1312 i = 0; 1327 if (sctx->addrs != NULL)
1313 while (sctx->addrs[i] != NULL) 1328 {
1314 { 1329 i = 0;
1315 GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Failed to start `%s' at `%s'\n"), 1330 while (sctx->addrs[i] != NULL)
1316 sctx->serviceName, GNUNET_a2s (sctx->addrs[i], 1331 {
1317 sctx->addrlens[i])); 1332 LOG (GNUNET_ERROR_TYPE_INFO,
1318 i++; 1333 _("Failed to start `%s' at `%s'\n"), sctx->serviceName,
1319 } 1334 GNUNET_a2s (sctx->addrs[i], sctx->addrlens[i]));
1335 i++;
1336 }
1337 }
1338 sctx->ret = GNUNET_SYSERR;
1339 return;
1320 } 1340 }
1321 sctx->ret = GNUNET_SYSERR;
1322 return;
1323 }
1324 if (0 == (sctx->options & GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN)) 1341 if (0 == (sctx->options & GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN))
1325 { 1342 {
1326 /* install a task that will kill the server 1343 /* install a task that will kill the server
1327 * process if the scheduler ever gets a shutdown signal */ 1344 * process if the scheduler ever gets a shutdown signal */
1328 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, 1345 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
1329 sctx->server); 1346 &shutdown_task, sctx->server);
1330 } 1347 }
1331 sctx->my_handlers = GNUNET_malloc (sizeof (defhandlers)); 1348 sctx->my_handlers = GNUNET_malloc (sizeof (defhandlers));
1332 memcpy (sctx->my_handlers, defhandlers, sizeof (defhandlers)); 1349 memcpy (sctx->my_handlers, defhandlers, sizeof (defhandlers));
1333 i = 0; 1350 i = 0;
@@ -1335,23 +1352,23 @@ service_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1335 sctx->my_handlers[i++].callback_cls = sctx; 1352 sctx->my_handlers[i++].callback_cls = sctx;
1336 GNUNET_SERVER_add_handlers (sctx->server, sctx->my_handlers); 1353 GNUNET_SERVER_add_handlers (sctx->server, sctx->my_handlers);
1337 if (sctx->ready_confirm_fd != -1) 1354 if (sctx->ready_confirm_fd != -1)
1338 { 1355 {
1339 GNUNET_break (1 == WRITE (sctx->ready_confirm_fd, ".", 1)); 1356 GNUNET_break (1 == WRITE (sctx->ready_confirm_fd, ".", 1));
1340 GNUNET_break (0 == CLOSE (sctx->ready_confirm_fd)); 1357 GNUNET_break (0 == CLOSE (sctx->ready_confirm_fd));
1341 sctx->ready_confirm_fd = -1; 1358 sctx->ready_confirm_fd = -1;
1342 write_pid_file (sctx, getpid ()); 1359 write_pid_file (sctx, getpid ());
1343 } 1360 }
1344 if (sctx->addrs != NULL) 1361 if (sctx->addrs != NULL)
1345 {
1346 i = 0;
1347 while (sctx->addrs[i] != NULL)
1348 { 1362 {
1349 GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Service `%s' runs at %s\n"), 1363 i = 0;
1350 sctx->serviceName, GNUNET_a2s (sctx->addrs[i], 1364 while (sctx->addrs[i] != NULL)
1351 sctx->addrlens[i])); 1365 {
1352 i++; 1366 LOG (GNUNET_ERROR_TYPE_INFO, _("Service `%s' runs at %s\n"),
1367 sctx->serviceName, GNUNET_a2s (sctx->addrs[i],
1368 sctx->addrlens[i]));
1369 i++;
1370 }
1353 } 1371 }
1354 }
1355 sctx->task (sctx->task_cls, sctx->server, sctx->cfg); 1372 sctx->task (sctx->task_cls, sctx->server, sctx->cfg);
1356} 1373}
1357 1374
@@ -1368,45 +1385,45 @@ detach_terminal (struct GNUNET_SERVICE_Context *sctx)
1368 int filedes[2]; 1385 int filedes[2];
1369 1386
1370 if (0 != PIPE (filedes)) 1387 if (0 != PIPE (filedes))
1371 { 1388 {
1372 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "pipe"); 1389 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "pipe");
1373 return GNUNET_SYSERR; 1390 return GNUNET_SYSERR;
1374 } 1391 }
1375 pid = fork (); 1392 pid = fork ();
1376 if (pid < 0) 1393 if (pid < 0)
1377 { 1394 {
1378 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "fork"); 1395 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "fork");
1379 return GNUNET_SYSERR; 1396 return GNUNET_SYSERR;
1380 } 1397 }
1381 if (pid != 0) 1398 if (pid != 0)
1382 {
1383 /* Parent */
1384 char c;
1385
1386 GNUNET_break (0 == CLOSE (filedes[1]));
1387 c = 'X';
1388 if (1 != READ (filedes[0], &c, sizeof (char)))
1389 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "read");
1390 fflush (stdout);
1391 switch (c)
1392 { 1399 {
1393 case '.': 1400 /* Parent */
1394 exit (0); 1401 char c;
1395 case 'I': 1402
1396 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1403 GNUNET_break (0 == CLOSE (filedes[1]));
1397 _("Service process failed to initialize\n")); 1404 c = 'X';
1398 break; 1405 if (1 != READ (filedes[0], &c, sizeof (char)))
1399 case 'S': 1406 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "read");
1400 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1407 fflush (stdout);
1401 _("Service process could not initialize server function\n")); 1408 switch (c)
1402 break; 1409 {
1403 case 'X': 1410 case '.':
1404 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1411 exit (0);
1405 _("Service process failed to report status\n")); 1412 case 'I':
1406 break; 1413 LOG (GNUNET_ERROR_TYPE_INFO,
1414 _("Service process failed to initialize\n"));
1415 break;
1416 case 'S':
1417 LOG (GNUNET_ERROR_TYPE_INFO,
1418 _("Service process could not initialize server function\n"));
1419 break;
1420 case 'X':
1421 LOG (GNUNET_ERROR_TYPE_INFO,
1422 _("Service process failed to report status\n"));
1423 break;
1424 }
1425 exit (1); /* child reported error */
1407 } 1426 }
1408 exit (1); /* child reported error */
1409 }
1410 GNUNET_break (0 == CLOSE (0)); 1427 GNUNET_break (0 == CLOSE (0));
1411 GNUNET_break (0 == CLOSE (1)); 1428 GNUNET_break (0 == CLOSE (1));
1412 GNUNET_break (0 == CLOSE (filedes[0])); 1429 GNUNET_break (0 == CLOSE (filedes[0]));
@@ -1415,16 +1432,16 @@ detach_terminal (struct GNUNET_SERVICE_Context *sctx)
1415 return GNUNET_SYSERR; 1432 return GNUNET_SYSERR;
1416 /* set stdin/stdout to /dev/null */ 1433 /* set stdin/stdout to /dev/null */
1417 if ((dup2 (nullfd, 0) < 0) || (dup2 (nullfd, 1) < 0)) 1434 if ((dup2 (nullfd, 0) < 0) || (dup2 (nullfd, 1) < 0))
1418 { 1435 {
1419 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "dup2"); 1436 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "dup2");
1420 (void) CLOSE (nullfd); 1437 (void) CLOSE (nullfd);
1421 return GNUNET_SYSERR; 1438 return GNUNET_SYSERR;
1422 } 1439 }
1423 (void) CLOSE (nullfd); 1440 (void) CLOSE (nullfd);
1424 /* Detach from controlling terminal */ 1441 /* Detach from controlling terminal */
1425 pid = setsid (); 1442 pid = setsid ();
1426 if (pid == -1) 1443 if (pid == -1)
1427 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "setsid"); 1444 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "setsid");
1428 sctx->ready_confirm_fd = filedes[1]; 1445 sctx->ready_confirm_fd = filedes[1];
1429#else 1446#else
1430 /* FIXME: we probably need to do something else 1447 /* FIXME: we probably need to do something else
@@ -1444,36 +1461,36 @@ set_user_id (struct GNUNET_SERVICE_Context *sctx)
1444 char *user; 1461 char *user;
1445 1462
1446 if (NULL == (user = get_user_name (sctx))) 1463 if (NULL == (user = get_user_name (sctx)))
1447 return GNUNET_OK; /* keep */ 1464 return GNUNET_OK; /* keep */
1448#ifndef MINGW 1465#ifndef MINGW
1449 struct passwd *pws; 1466 struct passwd *pws;
1450 1467
1451 errno = 0; 1468 errno = 0;
1452 pws = getpwnam (user); 1469 pws = getpwnam (user);
1453 if (pws == NULL) 1470 if (pws == NULL)
1454 { 1471 {
1455 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1472 LOG (GNUNET_ERROR_TYPE_ERROR,
1456 _("Cannot obtain information about user `%s': %s\n"), user, 1473 _("Cannot obtain information about user `%s': %s\n"), user,
1457 errno == 0 ? _("No such user") : STRERROR (errno)); 1474 errno == 0 ? _("No such user") : STRERROR (errno));
1458 GNUNET_free (user); 1475 GNUNET_free (user);
1459 return GNUNET_SYSERR; 1476 return GNUNET_SYSERR;
1460 } 1477 }
1461 if ((0 != setgid (pws->pw_gid)) || (0 != setegid (pws->pw_gid)) || 1478 if ((0 != setgid (pws->pw_gid)) || (0 != setegid (pws->pw_gid)) ||
1462#if HAVE_INITGROUPS 1479#if HAVE_INITGROUPS
1463 (0 != initgroups (user, pws->pw_gid)) || 1480 (0 != initgroups (user, pws->pw_gid)) ||
1464#endif 1481#endif
1465 (0 != setuid (pws->pw_uid)) || (0 != seteuid (pws->pw_uid))) 1482 (0 != setuid (pws->pw_uid)) || (0 != seteuid (pws->pw_uid)))
1466 {
1467 if ((0 != setregid (pws->pw_gid, pws->pw_gid)) ||
1468 (0 != setreuid (pws->pw_uid, pws->pw_uid)))
1469 { 1483 {
1470 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1484 if ((0 != setregid (pws->pw_gid, pws->pw_gid)) ||
1471 _("Cannot change user/group to `%s': %s\n"), user, 1485 (0 != setreuid (pws->pw_uid, pws->pw_uid)))
1472 STRERROR (errno)); 1486 {
1473 GNUNET_free (user); 1487 LOG (GNUNET_ERROR_TYPE_ERROR,
1474 return GNUNET_SYSERR; 1488 _("Cannot change user/group to `%s': %s\n"), user,
1489 STRERROR (errno));
1490 GNUNET_free (user);
1491 return GNUNET_SYSERR;
1492 }
1475 } 1493 }
1476 }
1477#endif 1494#endif
1478 GNUNET_free (user); 1495 GNUNET_free (user);
1479 return GNUNET_OK; 1496 return GNUNET_OK;
@@ -1489,9 +1506,9 @@ pid_file_delete (struct GNUNET_SERVICE_Context *sctx)
1489 char *pif = get_pid_file_name (sctx); 1506 char *pif = get_pid_file_name (sctx);
1490 1507
1491 if (pif == NULL) 1508 if (pif == NULL)
1492 return; /* no PID file */ 1509 return; /* no PID file */
1493 if (0 != UNLINK (pif)) 1510 if (0 != UNLINK (pif))
1494 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", pif); 1511 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "unlink", pif);
1495 GNUNET_free (pif); 1512 GNUNET_free (pif);
1496} 1513}
1497 1514
@@ -1511,8 +1528,8 @@ pid_file_delete (struct GNUNET_SERVICE_Context *sctx)
1511 */ 1528 */
1512int 1529int
1513GNUNET_SERVICE_run (int argc, char *const *argv, const char *serviceName, 1530GNUNET_SERVICE_run (int argc, char *const *argv, const char *serviceName,
1514 enum GNUNET_SERVICE_Options opt, GNUNET_SERVICE_Main task, 1531 enum GNUNET_SERVICE_Options opt, GNUNET_SERVICE_Main task,
1515 void *task_cls) 1532 void *task_cls)
1516{ 1533{
1517#define HANDLE_ERROR do { GNUNET_break (0); goto shutdown; } while (0) 1534#define HANDLE_ERROR do { GNUNET_break (0); goto shutdown; } while (0)
1518 1535
@@ -1568,24 +1585,24 @@ GNUNET_SERVICE_run (int argc, char *const *argv, const char *serviceName,
1568 if (GNUNET_OK != set_user_id (&sctx)) 1585 if (GNUNET_OK != set_user_id (&sctx))
1569 goto shutdown; 1586 goto shutdown;
1570#if DEBUG_SERVICE 1587#if DEBUG_SERVICE
1571 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1588 LOG (GNUNET_ERROR_TYPE_DEBUG,
1572 "Service `%s' runs with configuration from `%s'\n", serviceName, 1589 "Service `%s' runs with configuration from `%s'\n", serviceName,
1573 cfg_fn); 1590 cfg_fn);
1574#endif 1591#endif
1575 if (GNUNET_OK == 1592 if (GNUNET_OK ==
1576 GNUNET_CONFIGURATION_get_value_number (sctx.cfg, "testing", "skew_offset", 1593 GNUNET_CONFIGURATION_get_value_number (sctx.cfg, "testing",
1577 &skew_offset) && 1594 "skew_offset", &skew_offset)
1578 (GNUNET_OK == 1595 && (GNUNET_OK ==
1579 GNUNET_CONFIGURATION_get_value_number (sctx.cfg, "testing", 1596 GNUNET_CONFIGURATION_get_value_number (sctx.cfg, "testing",
1580 "skew_variance", &skew_variance))) 1597 "skew_variance",
1581 { 1598 &skew_variance)))
1582 clock_offset = skew_offset - skew_variance; 1599 {
1583 GNUNET_TIME_set_offset (clock_offset); 1600 clock_offset = skew_offset - skew_variance;
1601 GNUNET_TIME_set_offset (clock_offset);
1584#if DEBUG_SERVICE 1602#if DEBUG_SERVICE
1585 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Skewing clock by %dll\n", 1603 LOG (GNUNET_ERROR_TYPE_DEBUG, "Skewing clock by %dll\n", clock_offset);
1586 clock_offset);
1587#endif 1604#endif
1588 } 1605 }
1589 /* actually run service */ 1606 /* actually run service */
1590 err = 0; 1607 err = 0;
1591 GNUNET_SCHEDULER_run (&service_task, &sctx); 1608 GNUNET_SCHEDULER_run (&service_task, &sctx);
@@ -1597,11 +1614,11 @@ GNUNET_SERVICE_run (int argc, char *const *argv, const char *serviceName,
1597 1614
1598shutdown: 1615shutdown:
1599 if (sctx.ready_confirm_fd != -1) 1616 if (sctx.ready_confirm_fd != -1)
1600 { 1617 {
1601 if (1 != WRITE (sctx.ready_confirm_fd, err ? "I" : "S", 1)) 1618 if (1 != WRITE (sctx.ready_confirm_fd, err ? "I" : "S", 1))
1602 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "write"); 1619 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "write");
1603 GNUNET_break (0 == CLOSE (sctx.ready_confirm_fd)); 1620 GNUNET_break (0 == CLOSE (sctx.ready_confirm_fd));
1604 } 1621 }
1605 1622
1606 GNUNET_CONFIGURATION_destroy (cfg); 1623 GNUNET_CONFIGURATION_destroy (cfg);
1607 i = 0; 1624 i = 0;
@@ -1632,13 +1649,13 @@ shutdown:
1632 */ 1649 */
1633struct GNUNET_SERVICE_Context * 1650struct GNUNET_SERVICE_Context *
1634GNUNET_SERVICE_start (const char *serviceName, 1651GNUNET_SERVICE_start (const char *serviceName,
1635 const struct GNUNET_CONFIGURATION_Handle *cfg) 1652 const struct GNUNET_CONFIGURATION_Handle *cfg)
1636{ 1653{
1637 int i; 1654 int i;
1638 struct GNUNET_SERVICE_Context *sctx; 1655 struct GNUNET_SERVICE_Context *sctx;
1639 1656
1640 sctx = GNUNET_malloc (sizeof (struct GNUNET_SERVICE_Context)); 1657 sctx = GNUNET_malloc (sizeof (struct GNUNET_SERVICE_Context));
1641 sctx->ready_confirm_fd = -1; /* no daemonizing */ 1658 sctx->ready_confirm_fd = -1; /* no daemonizing */
1642 sctx->ret = GNUNET_OK; 1659 sctx->ret = GNUNET_OK;
1643 sctx->timeout = GNUNET_TIME_UNIT_FOREVER_REL; 1660 sctx->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
1644 sctx->serviceName = serviceName; 1661 sctx->serviceName = serviceName;
@@ -1646,24 +1663,24 @@ GNUNET_SERVICE_start (const char *serviceName,
1646 1663
1647 /* setup subsystems */ 1664 /* setup subsystems */
1648 if (GNUNET_OK != setup_service (sctx)) 1665 if (GNUNET_OK != setup_service (sctx))
1649 { 1666 {
1650 GNUNET_SERVICE_stop (sctx); 1667 GNUNET_SERVICE_stop (sctx);
1651 return NULL; 1668 return NULL;
1652 } 1669 }
1653 if (sctx->lsocks != NULL) 1670 if (sctx->lsocks != NULL)
1654 sctx->server = 1671 sctx->server =
1655 GNUNET_SERVER_create_with_sockets (&check_access, sctx, sctx->lsocks, 1672 GNUNET_SERVER_create_with_sockets (&check_access, sctx, sctx->lsocks,
1656 sctx->timeout, sctx->require_found); 1673 sctx->timeout, sctx->require_found);
1657 else 1674 else
1658 sctx->server = 1675 sctx->server =
1659 GNUNET_SERVER_create (&check_access, sctx, sctx->addrs, sctx->addrlens, 1676 GNUNET_SERVER_create (&check_access, sctx, sctx->addrs, sctx->addrlens,
1660 sctx->timeout, sctx->require_found); 1677 sctx->timeout, sctx->require_found);
1661 1678
1662 if (NULL == sctx->server) 1679 if (NULL == sctx->server)
1663 { 1680 {
1664 GNUNET_SERVICE_stop (sctx); 1681 GNUNET_SERVICE_stop (sctx);
1665 return NULL; 1682 return NULL;
1666 } 1683 }
1667 sctx->my_handlers = GNUNET_malloc (sizeof (defhandlers)); 1684 sctx->my_handlers = GNUNET_malloc (sizeof (defhandlers));
1668 memcpy (sctx->my_handlers, defhandlers, sizeof (defhandlers)); 1685 memcpy (sctx->my_handlers, defhandlers, sizeof (defhandlers));
1669 i = 0; 1686 i = 0;
@@ -1701,12 +1718,12 @@ GNUNET_SERVICE_stop (struct GNUNET_SERVICE_Context *sctx)
1701 GNUNET_SERVER_destroy (sctx->server); 1718 GNUNET_SERVER_destroy (sctx->server);
1702 GNUNET_free_non_null (sctx->my_handlers); 1719 GNUNET_free_non_null (sctx->my_handlers);
1703 if (sctx->addrs != NULL) 1720 if (sctx->addrs != NULL)
1704 { 1721 {
1705 i = 0; 1722 i = 0;
1706 while (sctx->addrs[i] != NULL) 1723 while (sctx->addrs[i] != NULL)
1707 GNUNET_free (sctx->addrs[i++]); 1724 GNUNET_free (sctx->addrs[i++]);
1708 GNUNET_free (sctx->addrs); 1725 GNUNET_free (sctx->addrs);
1709 } 1726 }
1710 GNUNET_free_non_null (sctx->addrlens); 1727 GNUNET_free_non_null (sctx->addrlens);
1711 GNUNET_free_non_null (sctx->v4_denied); 1728 GNUNET_free_non_null (sctx->v4_denied);
1712 GNUNET_free_non_null (sctx->v6_denied); 1729 GNUNET_free_non_null (sctx->v6_denied);