aboutsummaryrefslogtreecommitdiff
path: root/src/util/service.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/service.c')
-rw-r--r--src/util/service.c1459
1 files changed, 720 insertions, 739 deletions
diff --git a/src/util/service.c b/src/util/service.c
index ac5ce8d80..308267bd6 100644
--- a/src/util/service.c
+++ b/src/util/service.c
@@ -98,128 +98,123 @@ parse_ipv4_specification (const char *routeList)
98 i = 0; 98 i = 0;
99 pos = 0; 99 pos = 0;
100 while (i < count) 100 while (i < count)
101 {
102 cnt = sscanf (&routeList[pos],
103 "%u.%u.%u.%u/%u.%u.%u.%u;",
104 &temps[0],
105 &temps[1],
106 &temps[2],
107 &temps[3], &temps[4], &temps[5], &temps[6], &temps[7]);
108 if (cnt == 8)
101 { 109 {
102 cnt = sscanf (&routeList[pos], 110 for (j = 0; j < 8; j++)
103 "%u.%u.%u.%u/%u.%u.%u.%u;", 111 if (temps[j] > 0xFF)
104 &temps[0],
105 &temps[1],
106 &temps[2],
107 &temps[3], &temps[4], &temps[5], &temps[6], &temps[7]);
108 if (cnt == 8)
109 { 112 {
110 for (j = 0; j < 8; j++) 113 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
111 if (temps[j] > 0xFF) 114 _("Invalid format for IP: `%s'\n"), &routeList[pos]);
112 { 115 GNUNET_free (result);
113 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 116 return NULL;
114 _("Invalid format for IP: `%s'\n"),
115 &routeList[pos]);
116 GNUNET_free (result);
117 return NULL;
118 }
119 result[i].network.s_addr
120 =
121 htonl ((temps[0] << 24) + (temps[1] << 16) + (temps[2] << 8) +
122 temps[3]);
123 result[i].netmask.s_addr =
124 htonl ((temps[4] << 24) + (temps[5] << 16) + (temps[6] << 8) +
125 temps[7]);
126 while (routeList[pos] != ';')
127 pos++;
128 pos++;
129 i++;
130 continue;
131 } 117 }
132 /* try second notation */ 118 result[i].network.s_addr
133 cnt = sscanf (&routeList[pos], 119 =
134 "%u.%u.%u.%u/%u;", 120 htonl ((temps[0] << 24) + (temps[1] << 16) + (temps[2] << 8) +
135 &temps[0], &temps[1], &temps[2], &temps[3], &slash); 121 temps[3]);
136 if (cnt == 5) 122 result[i].netmask.s_addr =
123 htonl ((temps[4] << 24) + (temps[5] << 16) + (temps[6] << 8) +
124 temps[7]);
125 while (routeList[pos] != ';')
126 pos++;
127 pos++;
128 i++;
129 continue;
130 }
131 /* try second notation */
132 cnt = sscanf (&routeList[pos],
133 "%u.%u.%u.%u/%u;",
134 &temps[0], &temps[1], &temps[2], &temps[3], &slash);
135 if (cnt == 5)
136 {
137 for (j = 0; j < 4; j++)
138 if (temps[j] > 0xFF)
137 { 139 {
138 for (j = 0; j < 4; j++) 140 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
139 if (temps[j] > 0xFF) 141 _("Invalid format for IP: `%s'\n"), &routeList[pos]);
140 { 142 GNUNET_free (result);
141 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 143 return NULL;
142 _("Invalid format for IP: `%s'\n"),
143 &routeList[pos]);
144 GNUNET_free (result);
145 return NULL;
146 }
147 result[i].network.s_addr
148 =
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 GNUNET_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 } 144 }
177 /* try third notation */ 145 result[i].network.s_addr
178 slash = 32; 146 =
179 cnt = sscanf (&routeList[pos], 147 htonl ((temps[0] << 24) + (temps[1] << 16) + (temps[2] << 8) +
180 "%u.%u.%u.%u;", 148 temps[3]);
181 &temps[0], &temps[1], &temps[2], &temps[3]); 149 if ((slash <= 32) && (slash >= 0))
182 if (cnt == 4) 150 {
151 result[i].netmask.s_addr = 0;
152 while (slash > 0)
183 { 153 {
184 for (j = 0; j < 4; j++) 154 result[i].netmask.s_addr
185 if (temps[j] > 0xFF) 155 = (result[i].netmask.s_addr >> 1) + 0x80000000;
186 { 156 slash--;
187 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
188 _("Invalid format for IP: `%s'\n"),
189 &routeList[pos]);
190 GNUNET_free (result);
191 return NULL;
192 }
193 result[i].network.s_addr
194 =
195 htonl ((temps[0] << 24) + (temps[1] << 16) + (temps[2] << 8) +
196 temps[3]);
197 result[i].netmask.s_addr = 0;
198 while (slash > 0)
199 {
200 result[i].netmask.s_addr
201 = (result[i].netmask.s_addr >> 1) + 0x80000000;
202 slash--;
203 }
204 result[i].netmask.s_addr = htonl (result[i].netmask.s_addr);
205 while (routeList[pos] != ';')
206 pos++;
207 pos++;
208 i++;
209 continue;
210 } 157 }
211 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 158 result[i].netmask.s_addr = htonl (result[i].netmask.s_addr);
212 _("Invalid format for IP: `%s'\n"), &routeList[pos]); 159 while (routeList[pos] != ';')
213 GNUNET_free (result); 160 pos++;
214 return NULL; /* error */ 161 pos++;
162 i++;
163 continue;
164 }
165 else
166 {
167 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
168 _
169 ("Invalid network notation ('/%d' is not legal in IPv4 CIDR)."),
170 slash);
171 GNUNET_free (result);
172 return NULL; /* error */
173 }
215 } 174 }
216 if (pos < strlen (routeList)) 175 /* try third notation */
176 slash = 32;
177 cnt = sscanf (&routeList[pos],
178 "%u.%u.%u.%u;", &temps[0], &temps[1], &temps[2], &temps[3]);
179 if (cnt == 4)
217 { 180 {
218 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 181 for (j = 0; j < 4; j++)
219 _("Invalid format for IP: `%s'\n"), &routeList[pos]); 182 if (temps[j] > 0xFF)
220 GNUNET_free (result); 183 {
221 return NULL; /* oops */ 184 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
185 _("Invalid format for IP: `%s'\n"), &routeList[pos]);
186 GNUNET_free (result);
187 return NULL;
188 }
189 result[i].network.s_addr
190 =
191 htonl ((temps[0] << 24) + (temps[1] << 16) + (temps[2] << 8) +
192 temps[3]);
193 result[i].netmask.s_addr = 0;
194 while (slash > 0)
195 {
196 result[i].netmask.s_addr = (result[i].netmask.s_addr >> 1) + 0x80000000;
197 slash--;
198 }
199 result[i].netmask.s_addr = htonl (result[i].netmask.s_addr);
200 while (routeList[pos] != ';')
201 pos++;
202 pos++;
203 i++;
204 continue;
222 } 205 }
206 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
207 _("Invalid format for IP: `%s'\n"), &routeList[pos]);
208 GNUNET_free (result);
209 return NULL; /* error */
210 }
211 if (pos < strlen (routeList))
212 {
213 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
214 _("Invalid format for IP: `%s'\n"), &routeList[pos]);
215 GNUNET_free (result);
216 return NULL; /* oops */
217 }
223 return result; /* ok */ 218 return result; /* ok */
224} 219}
225 220
@@ -262,88 +257,85 @@ parse_ipv6_specification (const char *routeListX)
262 if (routeList[i] == ';') 257 if (routeList[i] == ';')
263 count++; 258 count++;
264 if (routeList[len - 1] != ';') 259 if (routeList[len - 1] != ';')
265 { 260 {
266 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 261 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
267 _ 262 _
268 ("Invalid network notation (does not end with ';': `%s')\n"), 263 ("Invalid network notation (does not end with ';': `%s')\n"),
269 routeList); 264 routeList);
270 GNUNET_free (routeList); 265 GNUNET_free (routeList);
271 return NULL; 266 return NULL;
272 } 267 }
273 268
274 result = GNUNET_malloc (sizeof (struct IPv6NetworkSet) * (count + 1)); 269 result = GNUNET_malloc (sizeof (struct IPv6NetworkSet) * (count + 1));
275 memset (result, 0, sizeof (struct IPv6NetworkSet) * (count + 1)); 270 memset (result, 0, sizeof (struct IPv6NetworkSet) * (count + 1));
276 i = 0; 271 i = 0;
277 pos = 0; 272 pos = 0;
278 while (i < count) 273 while (i < count)
274 {
275 start = pos;
276 while (routeList[pos] != ';')
277 pos++;
278 slash = pos;
279 while ((slash >= start) && (routeList[slash] != '/'))
280 slash--;
281 if (slash < start)
279 { 282 {
280 start = pos; 283 memset (&result[i].netmask, 0xFF, sizeof (struct in6_addr));
281 while (routeList[pos] != ';')
282 pos++;
283 slash = pos; 284 slash = pos;
284 while ((slash >= start) && (routeList[slash] != '/')) 285 }
285 slash--; 286 else
286 if (slash < start) 287 {
287 { 288 routeList[pos] = '\0';
288 memset (&result[i].netmask, 0xFF, sizeof (struct in6_addr)); 289 ret = inet_pton (AF_INET6, &routeList[slash + 1], &result[i].netmask);
289 slash = pos;
290 }
291 else
292 {
293 routeList[pos] = '\0';
294 ret = inet_pton (AF_INET6,
295 &routeList[slash + 1], &result[i].netmask);
296 if (ret <= 0)
297 {
298 save = errno;
299 if ((1 != SSCANF (&routeList[slash + 1],
300 "%u", &bits)) || (bits >= 128))
301 {
302 if (ret == 0)
303 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
304 _("Wrong format `%s' for netmask\n"),
305 &routeList[slash + 1]);
306 else
307 {
308 errno = save;
309 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
310 "inet_pton");
311 }
312 GNUNET_free (result);
313 GNUNET_free (routeList);
314 return NULL;
315 }
316 off = 0;
317 while (bits > 8)
318 {
319 result[i].netmask.s6_addr[off++] = 0xFF;
320 bits -= 8;
321 }
322 while (bits > 0)
323 {
324 result[i].netmask.s6_addr[off]
325 = (result[i].netmask.s6_addr[off] >> 1) + 0x80;
326 bits--;
327 }
328 }
329 }
330 routeList[slash] = '\0';
331 ret = inet_pton (AF_INET6, &routeList[start], &result[i].network);
332 if (ret <= 0) 290 if (ret <= 0)
291 {
292 save = errno;
293 if ((1 != SSCANF (&routeList[slash + 1], "%u", &bits)) || (bits >= 128))
333 { 294 {
334 if (ret == 0) 295 if (ret == 0)
335 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 296 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
336 _("Wrong format `%s' for network\n"), 297 _("Wrong format `%s' for netmask\n"),
337 &routeList[slash + 1]); 298 &routeList[slash + 1]);
338 else 299 else
339 GNUNET_log_strerror(GNUNET_ERROR_TYPE_ERROR, "inet_pton"); 300 {
301 errno = save;
302 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "inet_pton");
303 }
340 GNUNET_free (result); 304 GNUNET_free (result);
341 GNUNET_free (routeList); 305 GNUNET_free (routeList);
342 return NULL; 306 return NULL;
343 } 307 }
344 pos++; 308 off = 0;
345 i++; 309 while (bits > 8)
310 {
311 result[i].netmask.s6_addr[off++] = 0xFF;
312 bits -= 8;
313 }
314 while (bits > 0)
315 {
316 result[i].netmask.s6_addr[off]
317 = (result[i].netmask.s6_addr[off] >> 1) + 0x80;
318 bits--;
319 }
320 }
321 }
322 routeList[slash] = '\0';
323 ret = inet_pton (AF_INET6, &routeList[start], &result[i].network);
324 if (ret <= 0)
325 {
326 if (ret == 0)
327 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
328 _("Wrong format `%s' for network\n"),
329 &routeList[slash + 1]);
330 else
331 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "inet_pton");
332 GNUNET_free (result);
333 GNUNET_free (routeList);
334 return NULL;
346 } 335 }
336 pos++;
337 i++;
338 }
347 GNUNET_free (routeList); 339 GNUNET_free (routeList);
348 return result; 340 return result;
349} 341}
@@ -357,8 +349,7 @@ parse_ipv6_specification (const char *routeListX)
357 * @return GNUNET_NO if the IP is not in the list, GNUNET_YES if it it is 349 * @return GNUNET_NO if the IP is not in the list, GNUNET_YES if it it is
358 */ 350 */
359static int 351static int
360check_ipv4_listed (const struct IPv4NetworkSet *list, 352check_ipv4_listed (const struct IPv4NetworkSet *list, const struct in_addr *add)
361 const struct in_addr *add)
362{ 353{
363 int i; 354 int i;
364 355
@@ -367,12 +358,12 @@ check_ipv4_listed (const struct IPv4NetworkSet *list,
367 return GNUNET_NO; 358 return GNUNET_NO;
368 359
369 while ((list[i].network.s_addr != 0) || (list[i].netmask.s_addr != 0)) 360 while ((list[i].network.s_addr != 0) || (list[i].netmask.s_addr != 0))
370 { 361 {
371 if ((add->s_addr & list[i].netmask.s_addr) == 362 if ((add->s_addr & list[i].netmask.s_addr) ==
372 (list[i].network.s_addr & list[i].netmask.s_addr)) 363 (list[i].network.s_addr & list[i].netmask.s_addr))
373 return GNUNET_YES; 364 return GNUNET_YES;
374 i++; 365 i++;
375 } 366 }
376 return GNUNET_NO; 367 return GNUNET_NO;
377} 368}
378 369
@@ -384,8 +375,7 @@ check_ipv4_listed (const struct IPv4NetworkSet *list,
384 * @return GNUNET_NO if the IP is not in the list, GNUNET_YES if it it is 375 * @return GNUNET_NO if the IP is not in the list, GNUNET_YES if it it is
385 */ 376 */
386static int 377static int
387check_ipv6_listed (const struct IPv6NetworkSet *list, 378check_ipv6_listed (const struct IPv6NetworkSet *list, const struct in6_addr *ip)
388 const struct in6_addr *ip)
389{ 379{
390 unsigned int i; 380 unsigned int i;
391 unsigned int j; 381 unsigned int j;
@@ -398,16 +388,16 @@ check_ipv6_listed (const struct IPv6NetworkSet *list,
398 i = 0; 388 i = 0;
399NEXT: 389NEXT:
400 while (memcmp (&zero, &list[i].network, sizeof (struct in6_addr)) != 0) 390 while (memcmp (&zero, &list[i].network, sizeof (struct in6_addr)) != 0)
401 { 391 {
402 for (j = 0; j < sizeof (struct in6_addr) / sizeof (int); j++) 392 for (j = 0; j < sizeof (struct in6_addr) / sizeof (int); j++)
403 if (((((int *) ip)[j] & ((int *) &list[i].netmask)[j])) != 393 if (((((int *) ip)[j] & ((int *) &list[i].netmask)[j])) !=
404 (((int *) &list[i].network)[j] & ((int *) &list[i].netmask)[j])) 394 (((int *) &list[i].network)[j] & ((int *) &list[i].netmask)[j]))
405 { 395 {
406 i++; 396 i++;
407 goto NEXT; 397 goto NEXT;
408 } 398 }
409 return GNUNET_YES; 399 return GNUNET_YES;
410 } 400 }
411 return GNUNET_NO; 401 return GNUNET_NO;
412} 402}
413 403
@@ -482,7 +472,7 @@ struct GNUNET_SERVICE_Context
482 /** 472 /**
483 * Array of the lengths of the entries in addrs. 473 * Array of the lengths of the entries in addrs.
484 */ 474 */
485 socklen_t * addrlens; 475 socklen_t *addrlens;
486 476
487 /** 477 /**
488 * NULL-terminated array of listen sockets we should take over. 478 * NULL-terminated array of listen sockets we should take over.
@@ -541,10 +531,10 @@ write_test (void *cls, size_t size, void *buf)
541 struct GNUNET_MessageHeader *msg; 531 struct GNUNET_MessageHeader *msg;
542 532
543 if (size < sizeof (struct GNUNET_MessageHeader)) 533 if (size < sizeof (struct GNUNET_MessageHeader))
544 { 534 {
545 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 535 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
546 return 0; /* client disconnected */ 536 return 0; /* client disconnected */
547 } 537 }
548 msg = (struct GNUNET_MessageHeader *) buf; 538 msg = (struct GNUNET_MessageHeader *) buf;
549 msg->type = htons (GNUNET_MESSAGE_TYPE_TEST); 539 msg->type = htons (GNUNET_MESSAGE_TYPE_TEST);
550 msg->size = htons (sizeof (struct GNUNET_MessageHeader)); 540 msg->size = htons (sizeof (struct GNUNET_MessageHeader));
@@ -601,9 +591,9 @@ static const struct GNUNET_SERVER_MessageHandler defhandlers[] = {
601 * for unknown address family (will be denied). 591 * for unknown address family (will be denied).
602 */ 592 */
603static int 593static int
604check_access (void *cls, 594check_access (void *cls,
605 const struct GNUNET_CONNECTION_Credentials *uc, 595 const struct GNUNET_CONNECTION_Credentials *uc,
606 const struct sockaddr *addr, socklen_t addrlen) 596 const struct sockaddr *addr, socklen_t addrlen)
607{ 597{
608 struct GNUNET_SERVICE_Context *sctx = cls; 598 struct GNUNET_SERVICE_Context *sctx = cls;
609 const struct sockaddr_in *i4; 599 const struct sockaddr_in *i4;
@@ -611,57 +601,54 @@ check_access (void *cls,
611 int ret; 601 int ret;
612 602
613 switch (addr->sa_family) 603 switch (addr->sa_family)
614 { 604 {
615 case AF_INET: 605 case AF_INET:
616 GNUNET_assert (addrlen == sizeof (struct sockaddr_in)); 606 GNUNET_assert (addrlen == sizeof (struct sockaddr_in));
617 i4 = (const struct sockaddr_in *) addr; 607 i4 = (const struct sockaddr_in *) addr;
618 ret = ((sctx->v4_allowed == NULL) || 608 ret = ((sctx->v4_allowed == NULL) ||
619 (check_ipv4_listed (sctx->v4_allowed, 609 (check_ipv4_listed (sctx->v4_allowed,
620 &i4->sin_addr))) 610 &i4->sin_addr)))
621 && ((sctx->v4_denied == NULL) || 611 && ((sctx->v4_denied == NULL) ||
622 (!check_ipv4_listed (sctx->v4_denied, &i4->sin_addr))); 612 (!check_ipv4_listed (sctx->v4_denied, &i4->sin_addr)));
623 break; 613 break;
624 case AF_INET6: 614 case AF_INET6:
625 GNUNET_assert (addrlen == sizeof (struct sockaddr_in6)); 615 GNUNET_assert (addrlen == sizeof (struct sockaddr_in6));
626 i6 = (const struct sockaddr_in6 *) addr; 616 i6 = (const struct sockaddr_in6 *) addr;
627 ret = ((sctx->v6_allowed == NULL) || 617 ret = ((sctx->v6_allowed == NULL) ||
628 (check_ipv6_listed (sctx->v6_allowed, 618 (check_ipv6_listed (sctx->v6_allowed,
629 &i6->sin6_addr))) 619 &i6->sin6_addr)))
630 && ((sctx->v6_denied == NULL) || 620 && ((sctx->v6_denied == NULL) ||
631 (!check_ipv6_listed (sctx->v6_denied, &i6->sin6_addr))); 621 (!check_ipv6_listed (sctx->v6_denied, &i6->sin6_addr)));
632 break; 622 break;
633#ifndef WINDOWS 623#ifndef WINDOWS
634 case AF_UNIX: 624 case AF_UNIX:
635 ret = GNUNET_OK; /* always OK for now */ 625 ret = GNUNET_OK; /* always OK for now */
636 if ( (sctx->match_uid == GNUNET_YES) || 626 if ((sctx->match_uid == GNUNET_YES) || (sctx->match_gid == GNUNET_YES))
637 (sctx->match_gid == GNUNET_YES) ) 627 ret = GNUNET_NO;
638 ret = GNUNET_NO; 628 if ((uc != NULL) &&
639 if ( (uc != NULL) && 629 ((sctx->match_uid != GNUNET_YES) ||
640 ( (sctx->match_uid != GNUNET_YES) || 630 (uc->uid == geteuid ()) ||
641 (uc->uid == geteuid()) || 631 (uc->uid == getuid ())) &&
642 (uc->uid == getuid()) ) && 632 ((sctx->match_gid != GNUNET_YES) ||
643 ( (sctx->match_gid != GNUNET_YES) || 633 (uc->gid == getegid ()) || (uc->gid == getgid ())))
644 (uc->gid == getegid()) || 634 ret = GNUNET_YES;
645 (uc->gid == getgid())) ) 635 else
646 ret = GNUNET_YES;
647 else
648 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
649 _("Access denied to UID %d / GID %d\n"),
650 (uc == NULL) ? -1 : uc->uid,
651 (uc == NULL) ? -1 : uc->gid);
652 break;
653#endif
654 default:
655 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 636 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
656 _("Unknown address family %d\n"), addr->sa_family); 637 _("Access denied to UID %d / GID %d\n"),
657 return GNUNET_SYSERR; 638 (uc == NULL) ? -1 : uc->uid, (uc == NULL) ? -1 : uc->gid);
658 } 639 break;
640#endif
641 default:
642 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
643 _("Unknown address family %d\n"), addr->sa_family);
644 return GNUNET_SYSERR;
645 }
659 if (ret != GNUNET_OK) 646 if (ret != GNUNET_OK)
660 { 647 {
661 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 648 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
662 _("Access from `%s' denied to service `%s'\n"), 649 _("Access from `%s' denied to service `%s'\n"),
663 GNUNET_a2s (addr, addrlen), sctx->serviceName); 650 GNUNET_a2s (addr, addrlen), sctx->serviceName);
664 } 651 }
665 return ret; 652 return ret;
666} 653}
667 654
@@ -701,14 +688,14 @@ process_acl4 (struct IPv4NetworkSet **ret,
701 sctx->serviceName, 688 sctx->serviceName,
702 option, &opt)); 689 option, &opt));
703 if (NULL == (*ret = parse_ipv4_specification (opt))) 690 if (NULL == (*ret = parse_ipv4_specification (opt)))
704 { 691 {
705 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 692 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
706 _ 693 _
707 ("Could not parse IPv4 network specification `%s' for `%s:%s'\n"), 694 ("Could not parse IPv4 network specification `%s' for `%s:%s'\n"),
708 opt, sctx->serviceName, option); 695 opt, sctx->serviceName, option);
709 GNUNET_free (opt); 696 GNUNET_free (opt);
710 return GNUNET_SYSERR; 697 return GNUNET_SYSERR;
711 } 698 }
712 GNUNET_free (opt); 699 GNUNET_free (opt);
713 return GNUNET_OK; 700 return GNUNET_OK;
714} 701}
@@ -722,6 +709,7 @@ process_acl6 (struct IPv6NetworkSet **ret,
722 struct GNUNET_SERVICE_Context *sctx, const char *option) 709 struct GNUNET_SERVICE_Context *sctx, const char *option)
723{ 710{
724 char *opt; 711 char *opt;
712
725 if (!GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->serviceName, option)) 713 if (!GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->serviceName, option))
726 return GNUNET_OK; 714 return GNUNET_OK;
727 GNUNET_break (GNUNET_OK == 715 GNUNET_break (GNUNET_OK ==
@@ -729,14 +717,14 @@ process_acl6 (struct IPv6NetworkSet **ret,
729 sctx->serviceName, 717 sctx->serviceName,
730 option, &opt)); 718 option, &opt));
731 if (NULL == (*ret = parse_ipv6_specification (opt))) 719 if (NULL == (*ret = parse_ipv6_specification (opt)))
732 { 720 {
733 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 721 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
734 _ 722 _
735 ("Could not parse IPv6 network specification `%s' for `%s:%s'\n"), 723 ("Could not parse IPv6 network specification `%s' for `%s:%s'\n"),
736 opt, sctx->serviceName, option); 724 opt, sctx->serviceName, option);
737 GNUNET_free (opt); 725 GNUNET_free (opt);
738 return GNUNET_SYSERR; 726 return GNUNET_SYSERR;
739 } 727 }
740 GNUNET_free (opt); 728 GNUNET_free (opt);
741 return GNUNET_OK; 729 return GNUNET_OK;
742} 730}
@@ -751,10 +739,9 @@ process_acl6 (struct IPv6NetworkSet **ret,
751 */ 739 */
752static void 740static void
753add_unixpath (struct sockaddr **saddrs, 741add_unixpath (struct sockaddr **saddrs,
754 socklen_t *saddrlens, 742 socklen_t * saddrlens, const char *unixpath)
755 const char *unixpath)
756{ 743{
757#ifdef AF_UNIX 744#ifdef AF_UNIX
758 struct sockaddr_un *un; 745 struct sockaddr_un *un;
759 size_t slen; 746 size_t slen;
760 747
@@ -763,9 +750,7 @@ add_unixpath (struct sockaddr **saddrs,
763 slen = strlen (unixpath) + 1; 750 slen = strlen (unixpath) + 1;
764 if (slen >= sizeof (un->sun_path)) 751 if (slen >= sizeof (un->sun_path))
765 slen = sizeof (un->sun_path) - 1; 752 slen = sizeof (un->sun_path) - 1;
766 memcpy (un->sun_path, 753 memcpy (un->sun_path, unixpath, slen);
767 unixpath,
768 slen);
769 un->sun_path[slen] = '\0'; 754 un->sun_path[slen] = '\0';
770 slen = sizeof (struct sockaddr_un); 755 slen = sizeof (struct sockaddr_un);
771#if LINUX 756#if LINUX
@@ -774,11 +759,11 @@ add_unixpath (struct sockaddr **saddrs,
774#if HAVE_SOCKADDR_IN_SIN_LEN 759#if HAVE_SOCKADDR_IN_SIN_LEN
775 un->sun_len = (u_char) slen; 760 un->sun_len = (u_char) slen;
776#endif 761#endif
777 *saddrs = (struct sockaddr*) un; 762 *saddrs = (struct sockaddr *) un;
778 *saddrlens = slen; 763 *saddrlens = slen;
779#else 764#else
780 /* this function should never be called 765 /* this function should never be called
781 unless AF_UNIX is defined! */ 766 * unless AF_UNIX is defined! */
782 GNUNET_assert (0); 767 GNUNET_assert (0);
783#endif 768#endif
784} 769}
@@ -806,9 +791,9 @@ add_unixpath (struct sockaddr **saddrs,
806 */ 791 */
807int 792int
808GNUNET_SERVICE_get_server_addresses (const char *serviceName, 793GNUNET_SERVICE_get_server_addresses (const char *serviceName,
809 const struct GNUNET_CONFIGURATION_Handle *cfg, 794 const struct GNUNET_CONFIGURATION_Handle
810 struct sockaddr ***addrs, 795 *cfg, struct sockaddr ***addrs,
811 socklen_t **addr_lens) 796 socklen_t ** addr_lens)
812{ 797{
813 int disablev6; 798 int disablev6;
814 struct GNUNET_NETWORK_Handle *desc; 799 struct GNUNET_NETWORK_Handle *desc;
@@ -828,292 +813,282 @@ GNUNET_SERVICE_get_server_addresses (const char *serviceName,
828 *addrs = NULL; 813 *addrs = NULL;
829 *addr_lens = NULL; 814 *addr_lens = NULL;
830 desc = NULL; 815 desc = NULL;
831 if (GNUNET_CONFIGURATION_have_value (cfg, 816 if (GNUNET_CONFIGURATION_have_value (cfg, serviceName, "DISABLEV6"))
832 serviceName, "DISABLEV6")) 817 {
833 { 818 if (GNUNET_SYSERR ==
834 if (GNUNET_SYSERR == 819 (disablev6 = GNUNET_CONFIGURATION_get_value_yesno (cfg,
835 (disablev6 = GNUNET_CONFIGURATION_get_value_yesno (cfg, 820 serviceName,
836 serviceName, 821 "DISABLEV6")))
837 "DISABLEV6"))) 822 return GNUNET_SYSERR;
838 return GNUNET_SYSERR; 823 }
839 }
840 else 824 else
841 disablev6 = GNUNET_NO; 825 disablev6 = GNUNET_NO;
842 826
843 if (!disablev6) 827 if (!disablev6)
828 {
829 /* probe IPv6 support */
830 desc = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0);
831 if (NULL == desc)
844 { 832 {
845 /* probe IPv6 support */ 833 if ((errno == ENOBUFS) ||
846 desc = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0); 834 (errno == ENOMEM) || (errno == ENFILE) || (errno == EACCES))
847 if (NULL == desc) 835 {
848 { 836 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "socket");
849 if ((errno == ENOBUFS) || 837 return GNUNET_SYSERR;
850 (errno == ENOMEM) || (errno == ENFILE) || (errno == EACCES)) 838 }
851 { 839 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
852 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "socket"); 840 _
853 return GNUNET_SYSERR; 841 ("Disabling IPv6 support for service `%s', failed to create IPv6 socket: %s\n"),
854 } 842 serviceName, STRERROR (errno));
855 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 843 disablev6 = GNUNET_YES;
856 _
857 ("Disabling IPv6 support for service `%s', failed to create IPv6 socket: %s\n"),
858 serviceName, STRERROR (errno));
859 disablev6 = GNUNET_YES;
860 }
861 else
862 {
863 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (desc));
864 desc = NULL;
865 }
866 } 844 }
867 845 else
868 port = 0;
869 if (GNUNET_CONFIGURATION_have_value (cfg,
870 serviceName, "PORT"))
871 { 846 {
872 GNUNET_break (GNUNET_OK == 847 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (desc));
873 GNUNET_CONFIGURATION_get_value_number (cfg, 848 desc = NULL;
874 serviceName,
875 "PORT",
876 &port));
877 if (port > 65535)
878 {
879 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
880 _
881 ("Require valid port number for service `%s' in configuration!\n"),
882 serviceName);
883 return GNUNET_SYSERR;
884 }
885 } 849 }
850 }
886 851
887 if (GNUNET_CONFIGURATION_have_value (cfg, 852 port = 0;
888 serviceName, "BINDTO")) 853 if (GNUNET_CONFIGURATION_have_value (cfg, serviceName, "PORT"))
854 {
855 GNUNET_break (GNUNET_OK ==
856 GNUNET_CONFIGURATION_get_value_number (cfg,
857 serviceName,
858 "PORT", &port));
859 if (port > 65535)
889 { 860 {
890 GNUNET_break (GNUNET_OK == 861 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
891 GNUNET_CONFIGURATION_get_value_string (cfg, 862 _
892 serviceName, 863 ("Require valid port number for service `%s' in configuration!\n"),
893 "BINDTO", 864 serviceName);
894 &hostname)); 865 return GNUNET_SYSERR;
895 } 866 }
867 }
868
869 if (GNUNET_CONFIGURATION_have_value (cfg, serviceName, "BINDTO"))
870 {
871 GNUNET_break (GNUNET_OK ==
872 GNUNET_CONFIGURATION_get_value_string (cfg,
873 serviceName,
874 "BINDTO", &hostname));
875 }
896 else 876 else
897 hostname = NULL; 877 hostname = NULL;
898 878
899 unixpath = NULL; 879 unixpath = NULL;
900#ifdef AF_UNIX 880#ifdef AF_UNIX
901 if ((GNUNET_YES == GNUNET_CONFIGURATION_have_value (cfg, 881 if ((GNUNET_YES == GNUNET_CONFIGURATION_have_value (cfg,
902 serviceName, "UNIXPATH")) && 882 serviceName, "UNIXPATH"))
903 (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, 883 && (GNUNET_OK ==
904 serviceName, 884 GNUNET_CONFIGURATION_get_value_string (cfg, serviceName, "UNIXPATH",
905 "UNIXPATH", 885 &unixpath)) &&
906 &unixpath)) && 886 (0 < strlen (unixpath)))
907 (0 < strlen(unixpath))) 887 {
888 /* probe UNIX support */
889 struct sockaddr_un s_un;
890
891 if (strlen (unixpath) >= sizeof (s_un.sun_path))
908 { 892 {
909 /* probe UNIX support */ 893 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
910 struct sockaddr_un s_un; 894 _("UNIXPATH `%s' too long, maximum length is %llu\n"),
911 895 unixpath, sizeof (s_un.sun_path));
912 if (strlen(unixpath) >= sizeof(s_un.sun_path)) 896 GNUNET_free_non_null (hostname);
913 { 897 GNUNET_free (unixpath);
914 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 898 return GNUNET_SYSERR;
915 _("UNIXPATH `%s' too long, maximum length is %llu\n"),
916 unixpath,
917 sizeof(s_un.sun_path));
918 GNUNET_free_non_null (hostname);
919 GNUNET_free (unixpath);
920 return GNUNET_SYSERR;
921 }
922
923 desc = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0);
924 if (NULL == desc)
925 {
926 if ( (errno == ENOBUFS) ||
927 (errno == ENOMEM) || (errno == ENFILE) || (errno == EACCES))
928 {
929 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "socket");
930 GNUNET_free_non_null (hostname);
931 GNUNET_free (unixpath);
932 return GNUNET_SYSERR;
933 }
934 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
935 _
936 ("Disabling UNIX domain socket support for service `%s', failed to create UNIX domain socket: %s\n"),
937 serviceName, STRERROR (errno));
938 GNUNET_free (unixpath);
939 unixpath = NULL;
940 }
941 else
942 {
943 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (desc));
944 desc = NULL;
945 }
946 } 899 }
900
901 desc = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0);
902 if (NULL == desc)
903 {
904 if ((errno == ENOBUFS) ||
905 (errno == ENOMEM) || (errno == ENFILE) || (errno == EACCES))
906 {
907 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "socket");
908 GNUNET_free_non_null (hostname);
909 GNUNET_free (unixpath);
910 return GNUNET_SYSERR;
911 }
912 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
913 _
914 ("Disabling UNIX domain socket support for service `%s', failed to create UNIX domain socket: %s\n"),
915 serviceName, STRERROR (errno));
916 GNUNET_free (unixpath);
917 unixpath = NULL;
918 }
919 else
920 {
921 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (desc));
922 desc = NULL;
923 }
924 }
947#endif 925#endif
948 926
949 if ( (port == 0) && 927 if ((port == 0) && (unixpath == NULL))
950 (unixpath == NULL) ) 928 {
929 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
930 _
931 ("Have neither PORT nor UNIXPATH for service `%s', but one is required\n"),
932 serviceName);
933 GNUNET_free_non_null (hostname);
934 return GNUNET_SYSERR;
935 }
936 if (port == 0)
937 {
938 saddrs = GNUNET_malloc (2 * sizeof (struct sockaddr *));
939 saddrlens = GNUNET_malloc (2 * sizeof (socklen_t));
940 add_unixpath (saddrs, saddrlens, unixpath);
941 GNUNET_free_non_null (unixpath);
942 GNUNET_free_non_null (hostname);
943 *addrs = saddrs;
944 *addr_lens = saddrlens;
945 return 1;
946 }
947
948 if (hostname != NULL)
949 {
950#if DEBUG_SERVICE
951 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
952 "Resolving `%s' since that is where `%s' will bind to.\n",
953 hostname, serviceName);
954#endif
955 memset (&hints, 0, sizeof (struct addrinfo));
956 if (disablev6)
957 hints.ai_family = AF_INET;
958 if ((0 != (ret = getaddrinfo (hostname,
959 NULL, &hints, &res))) || (res == NULL))
951 { 960 {
952 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 961 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
953 _("Have neither PORT nor UNIXPATH for service `%s', but one is required\n"), 962 _("Failed to resolve `%s': %s\n"),
954 serviceName); 963 hostname, gai_strerror (ret));
955 GNUNET_free_non_null(hostname); 964 GNUNET_free (hostname);
965 GNUNET_free_non_null (unixpath);
956 return GNUNET_SYSERR; 966 return GNUNET_SYSERR;
957 } 967 }
958 if (port == 0) 968 next = res;
969 i = 0;
970 while (NULL != (pos = next))
959 { 971 {
960 saddrs = GNUNET_malloc (2 * sizeof(struct sockaddr*)); 972 next = pos->ai_next;
961 saddrlens = GNUNET_malloc (2 * sizeof (socklen_t)); 973 if ((disablev6) && (pos->ai_family == AF_INET6))
962 add_unixpath (saddrs, saddrlens, unixpath); 974 continue;
975 i++;
976 }
977 if (0 == i)
978 {
979 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
980 _("Failed to find %saddress for `%s'.\n"),
981 disablev6 ? "IPv4 " : "", hostname);
982 freeaddrinfo (res);
983 GNUNET_free (hostname);
963 GNUNET_free_non_null (unixpath); 984 GNUNET_free_non_null (unixpath);
964 GNUNET_free_non_null (hostname); 985 return GNUNET_SYSERR;
965 *addrs = saddrs;
966 *addr_lens = saddrlens;
967 return 1;
968 } 986 }
969 987 resi = i;
970 if (hostname != NULL) 988 if (NULL != unixpath)
989 resi++;
990 saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *));
991 saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t));
992 i = 0;
993 if (NULL != unixpath)
994 {
995 add_unixpath (saddrs, saddrlens, unixpath);
996 i++;
997 }
998 next = res;
999 while (NULL != (pos = next))
971 { 1000 {
1001 next = pos->ai_next;
1002 if ((disablev6) && (pos->ai_family == AF_INET6))
1003 continue;
1004 if ((pos->ai_protocol != IPPROTO_TCP) && (pos->ai_protocol != 0))
1005 continue; /* not TCP */
1006 if ((pos->ai_socktype != SOCK_STREAM) && (pos->ai_socktype != 0))
1007 continue; /* huh? */
972#if DEBUG_SERVICE 1008#if DEBUG_SERVICE
973 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1009 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
974 "Resolving `%s' since that is where `%s' will bind to.\n", 1010 "Service `%s' will bind to `%s'\n",
975 hostname, 1011 serviceName, GNUNET_a2s (pos->ai_addr, pos->ai_addrlen));
976 serviceName);
977#endif 1012#endif
978 memset (&hints, 0, sizeof (struct addrinfo)); 1013 if (pos->ai_family == AF_INET)
979 if (disablev6) 1014 {
980 hints.ai_family = AF_INET; 1015 GNUNET_assert (pos->ai_addrlen == sizeof (struct sockaddr_in));
981 if ((0 != (ret = getaddrinfo (hostname, 1016 saddrlens[i] = pos->ai_addrlen;
982 NULL, &hints, &res))) || (res == NULL)) 1017 saddrs[i] = GNUNET_malloc (saddrlens[i]);
983 { 1018 memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
984 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1019 ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
985 _("Failed to resolve `%s': %s\n"), 1020 }
986 hostname, gai_strerror (ret)); 1021 else
987 GNUNET_free (hostname); 1022 {
988 GNUNET_free_non_null (unixpath); 1023 GNUNET_assert (pos->ai_family == AF_INET6);
989 return GNUNET_SYSERR; 1024 GNUNET_assert (pos->ai_addrlen == sizeof (struct sockaddr_in6));
990 } 1025 saddrlens[i] = pos->ai_addrlen;
991 next = res; 1026 saddrs[i] = GNUNET_malloc (saddrlens[i]);
992 i = 0; 1027 memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
993 while (NULL != (pos = next)) 1028 ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
994 { 1029 }
995 next = pos->ai_next; 1030 i++;
996 if ( (disablev6) && (pos->ai_family == AF_INET6)) 1031 }
997 continue; 1032 GNUNET_free (hostname);
998 i++; 1033 freeaddrinfo (res);
999 } 1034 resi = i;
1000 if (0 == i) 1035 }
1001 { 1036 else
1002 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1037 {
1003 _("Failed to find %saddress for `%s'.\n"), 1038 /* will bind against everything, just set port */
1004 disablev6 ? "IPv4 " : "", hostname); 1039 if (disablev6)
1005 freeaddrinfo (res); 1040 {
1006 GNUNET_free (hostname); 1041 /* V4-only */
1007 GNUNET_free_non_null (unixpath); 1042 resi = 1;
1008 return GNUNET_SYSERR;
1009 }
1010 resi = i;
1011 if (NULL != unixpath) 1043 if (NULL != unixpath)
1012 resi++; 1044 resi++;
1013 saddrs = GNUNET_malloc ((resi+1) * sizeof(struct sockaddr*));
1014 saddrlens = GNUNET_malloc ((resi+1) * sizeof (socklen_t));
1015 i = 0; 1045 i = 0;
1046 saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *));
1047 saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t));
1016 if (NULL != unixpath) 1048 if (NULL != unixpath)
1017 { 1049 {
1018 add_unixpath (saddrs, saddrlens, unixpath); 1050 add_unixpath (saddrs, saddrlens, unixpath);
1019 i++; 1051 i++;
1020 } 1052 }
1021 next = res; 1053 saddrlens[i] = sizeof (struct sockaddr_in);
1022 while (NULL != (pos = next)) 1054 saddrs[i] = GNUNET_malloc (saddrlens[i]);
1023 { 1055#if HAVE_SOCKADDR_IN_SIN_LEN
1024 next = pos->ai_next; 1056 ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[i];
1025 if ( (disablev6) && (pos->ai_family == AF_INET6))
1026 continue;
1027 if ( (pos->ai_protocol != IPPROTO_TCP) && (pos->ai_protocol != 0) )
1028 continue; /* not TCP */
1029 if ( (pos->ai_socktype != SOCK_STREAM) && (pos->ai_socktype != 0) )
1030 continue; /* huh? */
1031#if DEBUG_SERVICE
1032 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1033 "Service `%s' will bind to `%s'\n",
1034 serviceName,
1035 GNUNET_a2s (pos->ai_addr,
1036 pos->ai_addrlen));
1037#endif 1057#endif
1038 if (pos->ai_family == AF_INET) 1058 ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
1039 { 1059 ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
1040 GNUNET_assert (pos->ai_addrlen == sizeof (struct sockaddr_in));
1041 saddrlens[i] = pos->ai_addrlen;
1042 saddrs[i] = GNUNET_malloc (saddrlens[i]);
1043 memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
1044 ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
1045 }
1046 else
1047 {
1048 GNUNET_assert (pos->ai_family == AF_INET6);
1049 GNUNET_assert (pos->ai_addrlen == sizeof (struct sockaddr_in6));
1050 saddrlens[i] = pos->ai_addrlen;
1051 saddrs[i] = GNUNET_malloc (saddrlens[i]);
1052 memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
1053 ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
1054 }
1055 i++;
1056 }
1057 GNUNET_free (hostname);
1058 freeaddrinfo (res);
1059 resi = i;
1060 } 1060 }
1061 else 1061 else
1062 { 1062 {
1063 /* will bind against everything, just set port */ 1063 /* dual stack */
1064 if (disablev6) 1064 resi = 2;
1065 { 1065 if (NULL != unixpath)
1066 /* V4-only */ 1066 resi++;
1067 resi = 1; 1067 saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *));
1068 if (NULL != unixpath) 1068 saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t));
1069 resi++; 1069 i = 0;
1070 i = 0; 1070 if (NULL != unixpath)
1071 saddrs = GNUNET_malloc ((resi+1) * sizeof(struct sockaddr*)); 1071 {
1072 saddrlens = GNUNET_malloc ((resi+1) * sizeof (socklen_t)); 1072 add_unixpath (saddrs, saddrlens, unixpath);
1073 if (NULL != unixpath) 1073 i++;
1074 { 1074 }
1075 add_unixpath (saddrs, saddrlens, unixpath); 1075 saddrlens[i] = sizeof (struct sockaddr_in6);
1076 i++; 1076 saddrs[i] = GNUNET_malloc (saddrlens[i]);
1077 }
1078 saddrlens[i] = sizeof (struct sockaddr_in);
1079 saddrs[i] = GNUNET_malloc (saddrlens[i]);
1080#if HAVE_SOCKADDR_IN_SIN_LEN
1081 ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[i];
1082#endif
1083 ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
1084 ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
1085 }
1086 else
1087 {
1088 /* dual stack */
1089 resi = 2;
1090 if (NULL != unixpath)
1091 resi++;
1092 saddrs = GNUNET_malloc ((resi+1) * sizeof(struct sockaddr*));
1093 saddrlens = GNUNET_malloc ((resi+1) * sizeof (socklen_t));
1094 i = 0;
1095 if (NULL != unixpath)
1096 {
1097 add_unixpath (saddrs, saddrlens, unixpath);
1098 i++;
1099 }
1100 saddrlens[i] = sizeof (struct sockaddr_in6);
1101 saddrs[i] = GNUNET_malloc (saddrlens[i]);
1102#if HAVE_SOCKADDR_IN_SIN_LEN 1077#if HAVE_SOCKADDR_IN_SIN_LEN
1103 ((struct sockaddr_in6 *) saddrs[i])->sin6_len = saddrlens[0]; 1078 ((struct sockaddr_in6 *) saddrs[i])->sin6_len = saddrlens[0];
1104#endif 1079#endif
1105 ((struct sockaddr_in6 *) saddrs[i])->sin6_family = AF_INET6; 1080 ((struct sockaddr_in6 *) saddrs[i])->sin6_family = AF_INET6;
1106 ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port); 1081 ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
1107 i++; 1082 i++;
1108 saddrlens[i] = sizeof (struct sockaddr_in); 1083 saddrlens[i] = sizeof (struct sockaddr_in);
1109 saddrs[i] = GNUNET_malloc (saddrlens[i]); 1084 saddrs[i] = GNUNET_malloc (saddrlens[i]);
1110#if HAVE_SOCKADDR_IN_SIN_LEN 1085#if HAVE_SOCKADDR_IN_SIN_LEN
1111 ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[1]; 1086 ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[1];
1112#endif 1087#endif
1113 ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET; 1088 ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
1114 ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port); 1089 ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
1115 }
1116 } 1090 }
1091 }
1117 GNUNET_free_non_null (unixpath); 1092 GNUNET_free_non_null (unixpath);
1118 *addrs = saddrs; 1093 *addrs = saddrs;
1119 *addr_lens = saddrlens; 1094 *addr_lens = saddrlens;
@@ -1143,6 +1118,7 @@ setup_service (struct GNUNET_SERVICE_Context *sctx)
1143{ 1118{
1144 struct GNUNET_TIME_Relative idleout; 1119 struct GNUNET_TIME_Relative idleout;
1145 int tolerant; 1120 int tolerant;
1121
1146#ifndef MINGW 1122#ifndef MINGW
1147 const char *lpid; 1123 const char *lpid;
1148 unsigned int pid; 1124 unsigned int pid;
@@ -1151,92 +1127,89 @@ setup_service (struct GNUNET_SERVICE_Context *sctx)
1151 int flags; 1127 int flags;
1152#endif 1128#endif
1153 1129
1154 if (GNUNET_CONFIGURATION_have_value (sctx->cfg, 1130 if (GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->serviceName, "TIMEOUT"))
1155 sctx->serviceName, "TIMEOUT")) 1131 {
1132 if (GNUNET_OK !=
1133 GNUNET_CONFIGURATION_get_value_time (sctx->cfg,
1134 sctx->serviceName,
1135 "TIMEOUT", &idleout))
1156 { 1136 {
1157 if (GNUNET_OK != 1137 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1158 GNUNET_CONFIGURATION_get_value_time (sctx->cfg, 1138 _("Specified value for `%s' of service `%s' is invalid\n"),
1159 sctx->serviceName, 1139 "TIMEOUT", sctx->serviceName);
1160 "TIMEOUT", &idleout)) 1140 return GNUNET_SYSERR;
1161 {
1162 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1163 _("Specified value for `%s' of service `%s' is invalid\n"),
1164 "TIMEOUT",
1165 sctx->serviceName);
1166 return GNUNET_SYSERR;
1167 }
1168 sctx->timeout = idleout;
1169 } 1141 }
1142 sctx->timeout = idleout;
1143 }
1170 else 1144 else
1171 sctx->timeout = GNUNET_TIME_UNIT_FOREVER_REL; 1145 sctx->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
1172 1146
1173 if (GNUNET_CONFIGURATION_have_value (sctx->cfg, 1147 if (GNUNET_CONFIGURATION_have_value (sctx->cfg,
1174 sctx->serviceName, "TOLERANT")) 1148 sctx->serviceName, "TOLERANT"))
1149 {
1150 if (GNUNET_SYSERR ==
1151 (tolerant = GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg,
1152 sctx->serviceName,
1153 "TOLERANT")))
1175 { 1154 {
1176 if (GNUNET_SYSERR == 1155 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1177 (tolerant = GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg, 1156 _("Specified value for `%s' of service `%s' is invalid\n"),
1178 sctx->serviceName, 1157 "TOLERANT", sctx->serviceName);
1179 "TOLERANT"))) 1158 return GNUNET_SYSERR;
1180 {
1181 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1182 _("Specified value for `%s' of service `%s' is invalid\n"),
1183 "TOLERANT",
1184 sctx->serviceName);
1185 return GNUNET_SYSERR;
1186 }
1187 } 1159 }
1160 }
1188 else 1161 else
1189 tolerant = GNUNET_NO; 1162 tolerant = GNUNET_NO;
1190 1163
1191#ifndef MINGW 1164#ifndef MINGW
1192 errno = 0; 1165 errno = 0;
1193 if ( (NULL != (lpid = getenv ("LISTEN_PID"))) && 1166 if ((NULL != (lpid = getenv ("LISTEN_PID"))) &&
1194 (1 == sscanf (lpid, "%u", &pid)) && 1167 (1 == sscanf (lpid, "%u", &pid)) &&
1195 (getpid () == (pid_t) pid) && 1168 (getpid () == (pid_t) pid) &&
1196 (NULL != (nfds = getenv ("LISTEN_FDS"))) && 1169 (NULL != (nfds = getenv ("LISTEN_FDS"))) &&
1197 (1 == sscanf (nfds, "%u", &cnt)) && 1170 (1 == sscanf (nfds, "%u", &cnt)) &&
1198 (cnt > 0) && 1171 (cnt > 0) && (cnt < FD_SETSIZE) && (cnt + 4 < FD_SETSIZE))
1199 (cnt < FD_SETSIZE) && 1172 {
1200 (cnt + 4 < FD_SETSIZE) ) 1173 sctx->lsocks =
1174 GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle *) * (cnt + 1));
1175 while (0 < cnt--)
1201 { 1176 {
1202 sctx->lsocks = GNUNET_malloc (sizeof(struct GNUNET_NETWORK_Handle*) * (cnt+1)); 1177 flags = fcntl (3 + cnt, F_GETFD);
1203 while (0 < cnt--) 1178 if ((flags < 0) ||
1204 { 1179 (0 != (flags & FD_CLOEXEC)) ||
1205 flags = fcntl (3 + cnt, F_GETFD); 1180 (NULL ==
1206 if ( (flags < 0) || 1181 (sctx->lsocks[cnt] = GNUNET_NETWORK_socket_box_native (3 + cnt))))
1207 (0 != (flags & FD_CLOEXEC)) || 1182 {
1208 (NULL == (sctx->lsocks[cnt] = GNUNET_NETWORK_socket_box_native (3 + cnt))) ) 1183 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1209 { 1184 _
1210 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1185 ("Could not access pre-bound socket %u, will try to bind myself\n"),
1211 _("Could not access pre-bound socket %u, will try to bind myself\n"), 1186 (unsigned int) 3 + cnt);
1212 (unsigned int) 3 +cnt); 1187 cnt++;
1213 cnt++; 1188 while (sctx->lsocks[cnt] != NULL)
1214 while (sctx->lsocks[cnt] != NULL) 1189 GNUNET_break (0 == GNUNET_NETWORK_socket_close (sctx->lsocks[cnt++]));
1215 GNUNET_break (0 == GNUNET_NETWORK_socket_close (sctx->lsocks[cnt++])); 1190 GNUNET_free (sctx->lsocks);
1216 GNUNET_free (sctx->lsocks); 1191 sctx->lsocks = NULL;
1217 sctx->lsocks = NULL; 1192 break;
1218 break; 1193 }
1219 }
1220 }
1221 unsetenv ("LISTEN_PID");
1222 unsetenv ("LISTEN_FDS");
1223 } 1194 }
1195 unsetenv ("LISTEN_PID");
1196 unsetenv ("LISTEN_FDS");
1197 }
1224#endif 1198#endif
1225 1199
1226 if ( (sctx->lsocks == NULL) && 1200 if ((sctx->lsocks == NULL) &&
1227 (GNUNET_SYSERR == 1201 (GNUNET_SYSERR ==
1228 GNUNET_SERVICE_get_server_addresses (sctx->serviceName, 1202 GNUNET_SERVICE_get_server_addresses (sctx->serviceName,
1229 sctx->cfg, 1203 sctx->cfg,
1230 &sctx->addrs, 1204 &sctx->addrs, &sctx->addrlens)))
1231 &sctx->addrlens)) )
1232 return GNUNET_SYSERR; 1205 return GNUNET_SYSERR;
1233 sctx->require_found = tolerant ? GNUNET_NO : GNUNET_YES; 1206 sctx->require_found = tolerant ? GNUNET_NO : GNUNET_YES;
1234 sctx->match_uid = GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg, 1207 sctx->match_uid = GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg,
1235 sctx->serviceName, 1208 sctx->serviceName,
1236 "UNIX_MATCH_UID"); 1209 "UNIX_MATCH_UID");
1237 sctx->match_gid = GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg, 1210 sctx->match_gid = GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg,
1238 sctx->serviceName, 1211 sctx->serviceName,
1239 "UNIX_MATCH_GID"); 1212 "UNIX_MATCH_GID");
1240 process_acl4 (&sctx->v4_denied, sctx, "REJECT_FROM"); 1213 process_acl4 (&sctx->v4_denied, sctx, "REJECT_FROM");
1241 process_acl4 (&sctx->v4_allowed, sctx, "ACCEPT_FROM"); 1214 process_acl4 (&sctx->v4_allowed, sctx, "ACCEPT_FROM");
1242 process_acl6 (&sctx->v6_denied, sctx, "REJECT_FROM6"); 1215 process_acl6 (&sctx->v6_denied, sctx, "REJECT_FROM6");
@@ -1285,30 +1258,30 @@ write_pid_file (struct GNUNET_SERVICE_Context *sctx, pid_t pid)
1285 len--; 1258 len--;
1286 rdir[len] = '\0'; 1259 rdir[len] = '\0';
1287 if (0 != ACCESS (rdir, F_OK)) 1260 if (0 != ACCESS (rdir, F_OK))
1288 { 1261 {
1289 /* we get to create a directory -- and claim it 1262 /* we get to create a directory -- and claim it
1290 as ours! */ 1263 * as ours! */
1291 GNUNET_DISK_directory_create (rdir); 1264 GNUNET_DISK_directory_create (rdir);
1292 if ((user != NULL) && (0 < strlen (user))) 1265 if ((user != NULL) && (0 < strlen (user)))
1293 GNUNET_DISK_file_change_owner (rdir, user); 1266 GNUNET_DISK_file_change_owner (rdir, user);
1294 } 1267 }
1295 if (0 != ACCESS (rdir, W_OK | X_OK)) 1268 if (0 != ACCESS (rdir, W_OK | X_OK))
1296 { 1269 {
1297 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "access", rdir); 1270 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "access", rdir);
1298 GNUNET_free (rdir); 1271 GNUNET_free (rdir);
1299 GNUNET_free_non_null (user); 1272 GNUNET_free_non_null (user);
1300 GNUNET_free (pif); 1273 GNUNET_free (pif);
1301 return GNUNET_SYSERR; 1274 return GNUNET_SYSERR;
1302 } 1275 }
1303 GNUNET_free (rdir); 1276 GNUNET_free (rdir);
1304 pidfd = FOPEN (pif, "w"); 1277 pidfd = FOPEN (pif, "w");
1305 if (pidfd == NULL) 1278 if (pidfd == NULL)
1306 { 1279 {
1307 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "fopen", pif); 1280 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "fopen", pif);
1308 GNUNET_free (pif); 1281 GNUNET_free (pif);
1309 GNUNET_free_non_null (user); 1282 GNUNET_free_non_null (user);
1310 return GNUNET_SYSERR; 1283 return GNUNET_SYSERR;
1311 } 1284 }
1312 if (0 > FPRINTF (pidfd, "%u", pid)) 1285 if (0 > FPRINTF (pidfd, "%u", pid))
1313 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "fprintf", pif); 1286 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "fprintf", pif);
1314 GNUNET_break (0 == fclose (pidfd)); 1287 GNUNET_break (0 == fclose (pidfd));
@@ -1347,39 +1320,40 @@ service_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1347 GNUNET_RESOLVER_connect (sctx->cfg); 1320 GNUNET_RESOLVER_connect (sctx->cfg);
1348 if (sctx->lsocks != NULL) 1321 if (sctx->lsocks != NULL)
1349 sctx->server = GNUNET_SERVER_create_with_sockets (&check_access, 1322 sctx->server = GNUNET_SERVER_create_with_sockets (&check_access,
1350 sctx, 1323 sctx,
1351 sctx->lsocks, 1324 sctx->lsocks,
1352 sctx->timeout, sctx->require_found); 1325 sctx->timeout,
1326 sctx->require_found);
1353 else 1327 else
1354 sctx->server = GNUNET_SERVER_create (&check_access, 1328 sctx->server = GNUNET_SERVER_create (&check_access,
1355 sctx, 1329 sctx,
1356 sctx->addrs, 1330 sctx->addrs,
1357 sctx->addrlens, 1331 sctx->addrlens,
1358 sctx->timeout, sctx->require_found); 1332 sctx->timeout, sctx->require_found);
1359 if (sctx->server == NULL) 1333 if (sctx->server == NULL)
1334 {
1335 if (sctx->addrs != NULL)
1360 { 1336 {
1361 if (sctx->addrs != NULL) 1337 i = 0;
1362 { 1338 while (sctx->addrs[i] != NULL)
1363 i = 0; 1339 {
1364 while (sctx->addrs[i] != NULL) 1340 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1365 { 1341 _("Failed to start `%s' at `%s'\n"),
1366 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1342 sctx->serviceName,
1367 _("Failed to start `%s' at `%s'\n"), 1343 GNUNET_a2s (sctx->addrs[i], sctx->addrlens[i]));
1368 sctx->serviceName, 1344 i++;
1369 GNUNET_a2s (sctx->addrs[i], sctx->addrlens[i])); 1345 }
1370 i++;
1371 }
1372 }
1373 sctx->ret = GNUNET_SYSERR;
1374 return;
1375 } 1346 }
1347 sctx->ret = GNUNET_SYSERR;
1348 return;
1349 }
1376 if (0 == (sctx->options & GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN)) 1350 if (0 == (sctx->options & GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN))
1377 { 1351 {
1378 /* install a task that will kill the server 1352 /* install a task that will kill the server
1379 process if the scheduler ever gets a shutdown signal */ 1353 * process if the scheduler ever gets a shutdown signal */
1380 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, 1354 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
1381 &shutdown_task, sctx->server); 1355 &shutdown_task, sctx->server);
1382 } 1356 }
1383 sctx->my_handlers = GNUNET_malloc (sizeof (defhandlers)); 1357 sctx->my_handlers = GNUNET_malloc (sizeof (defhandlers));
1384 memcpy (sctx->my_handlers, defhandlers, sizeof (defhandlers)); 1358 memcpy (sctx->my_handlers, defhandlers, sizeof (defhandlers));
1385 i = 0; 1359 i = 0;
@@ -1387,24 +1361,24 @@ service_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1387 sctx->my_handlers[i++].callback_cls = sctx; 1361 sctx->my_handlers[i++].callback_cls = sctx;
1388 GNUNET_SERVER_add_handlers (sctx->server, sctx->my_handlers); 1362 GNUNET_SERVER_add_handlers (sctx->server, sctx->my_handlers);
1389 if (sctx->ready_confirm_fd != -1) 1363 if (sctx->ready_confirm_fd != -1)
1390 { 1364 {
1391 GNUNET_break (1 == WRITE (sctx->ready_confirm_fd, ".", 1)); 1365 GNUNET_break (1 == WRITE (sctx->ready_confirm_fd, ".", 1));
1392 GNUNET_break (0 == CLOSE (sctx->ready_confirm_fd)); 1366 GNUNET_break (0 == CLOSE (sctx->ready_confirm_fd));
1393 sctx->ready_confirm_fd = -1; 1367 sctx->ready_confirm_fd = -1;
1394 write_pid_file (sctx, getpid ()); 1368 write_pid_file (sctx, getpid ());
1395 } 1369 }
1396 if (sctx->addrs != NULL) 1370 if (sctx->addrs != NULL)
1371 {
1372 i = 0;
1373 while (sctx->addrs[i] != NULL)
1397 { 1374 {
1398 i = 0; 1375 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1399 while (sctx->addrs[i] != NULL) 1376 _("Service `%s' runs at %s\n"),
1400 { 1377 sctx->serviceName,
1401 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1378 GNUNET_a2s (sctx->addrs[i], sctx->addrlens[i]));
1402 _("Service `%s' runs at %s\n"), 1379 i++;
1403 sctx->serviceName,
1404 GNUNET_a2s (sctx->addrs[i], sctx->addrlens[i]));
1405 i++;
1406 }
1407 } 1380 }
1381 }
1408 sctx->task (sctx->task_cls, sctx->server, sctx->cfg); 1382 sctx->task (sctx->task_cls, sctx->server, sctx->cfg);
1409} 1383}
1410 1384
@@ -1421,46 +1395,45 @@ detach_terminal (struct GNUNET_SERVICE_Context *sctx)
1421 int filedes[2]; 1395 int filedes[2];
1422 1396
1423 if (0 != PIPE (filedes)) 1397 if (0 != PIPE (filedes))
1424 { 1398 {
1425 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "pipe"); 1399 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "pipe");
1426 return GNUNET_SYSERR; 1400 return GNUNET_SYSERR;
1427 } 1401 }
1428 pid = fork (); 1402 pid = fork ();
1429 if (pid < 0) 1403 if (pid < 0)
1430 { 1404 {
1431 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "fork"); 1405 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "fork");
1432 return GNUNET_SYSERR; 1406 return GNUNET_SYSERR;
1433 } 1407 }
1434 if (pid != 0) 1408 if (pid != 0)
1409 {
1410 /* Parent */
1411 char c;
1412
1413 GNUNET_break (0 == CLOSE (filedes[1]));
1414 c = 'X';
1415 if (1 != READ (filedes[0], &c, sizeof (char)))
1416 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "read");
1417 fflush (stdout);
1418 switch (c)
1435 { 1419 {
1436 /* Parent */ 1420 case '.':
1437 char c; 1421 exit (0);
1438 1422 case 'I':
1439 GNUNET_break (0 == CLOSE (filedes[1])); 1423 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1440 c = 'X'; 1424 _("Service process failed to initialize\n"));
1441 if (1 != READ (filedes[0], &c, sizeof (char))) 1425 break;
1442 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "read"); 1426 case 'S':
1443 fflush (stdout); 1427 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1444 switch (c) 1428 _("Service process could not initialize server function\n"));
1445 { 1429 break;
1446 case '.': 1430 case 'X':
1447 exit (0); 1431 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1448 case 'I': 1432 _("Service process failed to report status\n"));
1449 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1433 break;
1450 _("Service process failed to initialize\n"));
1451 break;
1452 case 'S':
1453 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1454 _
1455 ("Service process could not initialize server function\n"));
1456 break;
1457 case 'X':
1458 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1459 _("Service process failed to report status\n"));
1460 break;
1461 }
1462 exit (1); /* child reported error */
1463 } 1434 }
1435 exit (1); /* child reported error */
1436 }
1464 GNUNET_break (0 == CLOSE (0)); 1437 GNUNET_break (0 == CLOSE (0));
1465 GNUNET_break (0 == CLOSE (1)); 1438 GNUNET_break (0 == CLOSE (1));
1466 GNUNET_break (0 == CLOSE (filedes[0])); 1439 GNUNET_break (0 == CLOSE (filedes[0]));
@@ -1469,11 +1442,11 @@ detach_terminal (struct GNUNET_SERVICE_Context *sctx)
1469 return GNUNET_SYSERR; 1442 return GNUNET_SYSERR;
1470 /* set stdin/stdout to /dev/null */ 1443 /* set stdin/stdout to /dev/null */
1471 if ((dup2 (nullfd, 0) < 0) || (dup2 (nullfd, 1) < 0)) 1444 if ((dup2 (nullfd, 0) < 0) || (dup2 (nullfd, 1) < 0))
1472 { 1445 {
1473 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "dup2"); 1446 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "dup2");
1474 (void) CLOSE (nullfd); 1447 (void) CLOSE (nullfd);
1475 return GNUNET_SYSERR; 1448 return GNUNET_SYSERR;
1476 } 1449 }
1477 (void) CLOSE (nullfd); 1450 (void) CLOSE (nullfd);
1478 /* Detach from controlling terminal */ 1451 /* Detach from controlling terminal */
1479 pid = setsid (); 1452 pid = setsid ();
@@ -1482,7 +1455,7 @@ detach_terminal (struct GNUNET_SERVICE_Context *sctx)
1482 sctx->ready_confirm_fd = filedes[1]; 1455 sctx->ready_confirm_fd = filedes[1];
1483#else 1456#else
1484 /* FIXME: we probably need to do something else 1457 /* FIXME: we probably need to do something else
1485 elsewhere in order to fork the process itself... */ 1458 * elsewhere in order to fork the process itself... */
1486 FreeConsole (); 1459 FreeConsole ();
1487#endif 1460#endif
1488 return GNUNET_OK; 1461 return GNUNET_OK;
@@ -1505,29 +1478,29 @@ set_user_id (struct GNUNET_SERVICE_Context *sctx)
1505 errno = 0; 1478 errno = 0;
1506 pws = getpwnam (user); 1479 pws = getpwnam (user);
1507 if (pws == NULL) 1480 if (pws == NULL)
1508 { 1481 {
1509 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1482 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1510 _("Cannot obtain information about user `%s': %s\n"), 1483 _("Cannot obtain information about user `%s': %s\n"),
1511 user, errno == 0 ? _("No such user") : STRERROR (errno)); 1484 user, errno == 0 ? _("No such user") : STRERROR (errno));
1512 GNUNET_free (user); 1485 GNUNET_free (user);
1513 return GNUNET_SYSERR; 1486 return GNUNET_SYSERR;
1514 } 1487 }
1515 if ((0 != setgid (pws->pw_gid)) || (0 != setegid (pws->pw_gid)) || 1488 if ((0 != setgid (pws->pw_gid)) || (0 != setegid (pws->pw_gid)) ||
1516#if HAVE_INITGROUPS 1489#if HAVE_INITGROUPS
1517 (0 != initgroups (user, pws->pw_gid)) || 1490 (0 != initgroups (user, pws->pw_gid)) ||
1518#endif 1491#endif
1519 (0 != setuid (pws->pw_uid)) || (0 != seteuid (pws->pw_uid))) 1492 (0 != setuid (pws->pw_uid)) || (0 != seteuid (pws->pw_uid)))
1493 {
1494 if ((0 != setregid (pws->pw_gid, pws->pw_gid)) ||
1495 (0 != setreuid (pws->pw_uid, pws->pw_uid)))
1520 { 1496 {
1521 if ((0 != setregid (pws->pw_gid, pws->pw_gid)) || 1497 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1522 (0 != setreuid (pws->pw_uid, pws->pw_uid))) 1498 _("Cannot change user/group to `%s': %s\n"), user,
1523 { 1499 STRERROR (errno));
1524 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1500 GNUNET_free (user);
1525 _("Cannot change user/group to `%s': %s\n"), user, 1501 return GNUNET_SYSERR;
1526 STRERROR (errno));
1527 GNUNET_free (user);
1528 return GNUNET_SYSERR;
1529 }
1530 } 1502 }
1503 }
1531#endif 1504#endif
1532 GNUNET_free (user); 1505 GNUNET_free (user);
1533 return GNUNET_OK; 1506 return GNUNET_OK;
@@ -1541,6 +1514,7 @@ static void
1541pid_file_delete (struct GNUNET_SERVICE_Context *sctx) 1514pid_file_delete (struct GNUNET_SERVICE_Context *sctx)
1542{ 1515{
1543 char *pif = get_pid_file_name (sctx); 1516 char *pif = get_pid_file_name (sctx);
1517
1544 if (pif == NULL) 1518 if (pif == NULL)
1545 return; /* no PID file */ 1519 return; /* no PID file */
1546 if (0 != UNLINK (pif)) 1520 if (0 != UNLINK (pif))
@@ -1582,6 +1556,7 @@ GNUNET_SERVICE_run (int argc,
1582 long long clock_offset; 1556 long long clock_offset;
1583 struct GNUNET_SERVICE_Context sctx; 1557 struct GNUNET_SERVICE_Context sctx;
1584 struct GNUNET_CONFIGURATION_Handle *cfg; 1558 struct GNUNET_CONFIGURATION_Handle *cfg;
1559
1585 struct GNUNET_GETOPT_CommandLineOption service_options[] = { 1560 struct GNUNET_GETOPT_CommandLineOption service_options[] = {
1586 GNUNET_GETOPT_OPTION_CFG_FILE (&cfg_fn), 1561 GNUNET_GETOPT_OPTION_CFG_FILE (&cfg_fn),
1587 {'d', "daemonize", NULL, 1562 {'d', "daemonize", NULL,
@@ -1609,7 +1584,7 @@ GNUNET_SERVICE_run (int argc,
1609 sctx.cfg = cfg = GNUNET_CONFIGURATION_create (); 1584 sctx.cfg = cfg = GNUNET_CONFIGURATION_create ();
1610 /* setup subsystems */ 1585 /* setup subsystems */
1611 if (GNUNET_SYSERR == GNUNET_GETOPT_run (serviceName, service_options, argc, 1586 if (GNUNET_SYSERR == GNUNET_GETOPT_run (serviceName, service_options, argc,
1612 argv)) 1587 argv))
1613 goto shutdown; 1588 goto shutdown;
1614 if (GNUNET_OK != GNUNET_log_setup (serviceName, loglev, logfile)) 1589 if (GNUNET_OK != GNUNET_log_setup (serviceName, loglev, logfile))
1615 HANDLE_ERROR; 1590 HANDLE_ERROR;
@@ -1617,7 +1592,7 @@ GNUNET_SERVICE_run (int argc,
1617 goto shutdown; 1592 goto shutdown;
1618 if (GNUNET_OK != setup_service (&sctx)) 1593 if (GNUNET_OK != setup_service (&sctx))
1619 goto shutdown; 1594 goto shutdown;
1620 if ( (do_daemonize == 1) && (GNUNET_OK != detach_terminal (&sctx))) 1595 if ((do_daemonize == 1) && (GNUNET_OK != detach_terminal (&sctx)))
1621 HANDLE_ERROR; 1596 HANDLE_ERROR;
1622 if (GNUNET_OK != set_user_id (&sctx)) 1597 if (GNUNET_OK != set_user_id (&sctx))
1623 goto shutdown; 1598 goto shutdown;
@@ -1626,15 +1601,20 @@ GNUNET_SERVICE_run (int argc,
1626 "Service `%s' runs with configuration from `%s'\n", 1601 "Service `%s' runs with configuration from `%s'\n",
1627 serviceName, cfg_fn); 1602 serviceName, cfg_fn);
1628#endif 1603#endif
1629 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number(sctx.cfg, "testing", "skew_offset", &skew_offset) && 1604 if (GNUNET_OK ==
1630 (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number(sctx.cfg, "testing", "skew_variance", &skew_variance))) 1605 GNUNET_CONFIGURATION_get_value_number (sctx.cfg, "testing", "skew_offset",
1631 { 1606 &skew_offset) &&
1632 clock_offset = skew_offset - skew_variance; 1607 (GNUNET_OK ==
1633 GNUNET_TIME_set_offset(clock_offset); 1608 GNUNET_CONFIGURATION_get_value_number (sctx.cfg, "testing",
1609 "skew_variance", &skew_variance)))
1610 {
1611 clock_offset = skew_offset - skew_variance;
1612 GNUNET_TIME_set_offset (clock_offset);
1634#if DEBUG_SERVICE 1613#if DEBUG_SERVICE
1635 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Skewing clock by %dll\n", clock_offset); 1614 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Skewing clock by %dll\n",
1615 clock_offset);
1636#endif 1616#endif
1637 } 1617 }
1638 /* actually run service */ 1618 /* actually run service */
1639 GNUNET_SCHEDULER_run (&service_task, &sctx); 1619 GNUNET_SCHEDULER_run (&service_task, &sctx);
1640 1620
@@ -1645,17 +1625,17 @@ GNUNET_SERVICE_run (int argc,
1645 1625
1646shutdown: 1626shutdown:
1647 if (sctx.ready_confirm_fd != -1) 1627 if (sctx.ready_confirm_fd != -1)
1648 { 1628 {
1649 if (1 != WRITE (sctx.ready_confirm_fd, err ? "I" : "S", 1)) 1629 if (1 != WRITE (sctx.ready_confirm_fd, err ? "I" : "S", 1))
1650 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "write"); 1630 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "write");
1651 GNUNET_break (0 == CLOSE (sctx.ready_confirm_fd)); 1631 GNUNET_break (0 == CLOSE (sctx.ready_confirm_fd));
1652 } 1632 }
1653 1633
1654 GNUNET_CONFIGURATION_destroy (cfg); 1634 GNUNET_CONFIGURATION_destroy (cfg);
1655 i = 0; 1635 i = 0;
1656 if (sctx.addrs != NULL) 1636 if (sctx.addrs != NULL)
1657 while (sctx.addrs[i] != NULL) 1637 while (sctx.addrs[i] != NULL)
1658 GNUNET_free (sctx.addrs[i++]); 1638 GNUNET_free (sctx.addrs[i++]);
1659 GNUNET_free_non_null (sctx.addrs); 1639 GNUNET_free_non_null (sctx.addrs);
1660 GNUNET_free_non_null (sctx.addrlens); 1640 GNUNET_free_non_null (sctx.addrlens);
1661 GNUNET_free_non_null (logfile); 1641 GNUNET_free_non_null (logfile);
@@ -1694,28 +1674,28 @@ GNUNET_SERVICE_start (const char *serviceName,
1694 1674
1695 /* setup subsystems */ 1675 /* setup subsystems */
1696 if (GNUNET_OK != setup_service (sctx)) 1676 if (GNUNET_OK != setup_service (sctx))
1697 { 1677 {
1698 GNUNET_SERVICE_stop (sctx); 1678 GNUNET_SERVICE_stop (sctx);
1699 return NULL; 1679 return NULL;
1700 } 1680 }
1701 if (sctx->lsocks != NULL) 1681 if (sctx->lsocks != NULL)
1702 sctx->server = GNUNET_SERVER_create_with_sockets (&check_access, 1682 sctx->server = GNUNET_SERVER_create_with_sockets (&check_access,
1703 sctx, 1683 sctx,
1704 sctx->lsocks, 1684 sctx->lsocks,
1705 sctx->timeout, sctx->require_found); 1685 sctx->timeout,
1686 sctx->require_found);
1706 else 1687 else
1707 sctx->server = GNUNET_SERVER_create (&check_access, 1688 sctx->server = GNUNET_SERVER_create (&check_access,
1708 sctx, 1689 sctx,
1709 sctx->addrs, 1690 sctx->addrs,
1710 sctx->addrlens, 1691 sctx->addrlens,
1711 sctx->timeout, 1692 sctx->timeout, sctx->require_found);
1712 sctx->require_found); 1693
1713
1714 if (NULL == sctx->server) 1694 if (NULL == sctx->server)
1715 { 1695 {
1716 GNUNET_SERVICE_stop (sctx); 1696 GNUNET_SERVICE_stop (sctx);
1717 return NULL; 1697 return NULL;
1718 } 1698 }
1719 sctx->my_handlers = GNUNET_malloc (sizeof (defhandlers)); 1699 sctx->my_handlers = GNUNET_malloc (sizeof (defhandlers));
1720 memcpy (sctx->my_handlers, defhandlers, sizeof (defhandlers)); 1700 memcpy (sctx->my_handlers, defhandlers, sizeof (defhandlers));
1721 i = 0; 1701 i = 0;
@@ -1748,16 +1728,17 @@ void
1748GNUNET_SERVICE_stop (struct GNUNET_SERVICE_Context *sctx) 1728GNUNET_SERVICE_stop (struct GNUNET_SERVICE_Context *sctx)
1749{ 1729{
1750 unsigned int i; 1730 unsigned int i;
1731
1751 if (NULL != sctx->server) 1732 if (NULL != sctx->server)
1752 GNUNET_SERVER_destroy (sctx->server); 1733 GNUNET_SERVER_destroy (sctx->server);
1753 GNUNET_free_non_null (sctx->my_handlers); 1734 GNUNET_free_non_null (sctx->my_handlers);
1754 if (sctx->addrs != NULL) 1735 if (sctx->addrs != NULL)
1755 { 1736 {
1756 i = 0; 1737 i = 0;
1757 while (sctx->addrs[i] != NULL) 1738 while (sctx->addrs[i] != NULL)
1758 GNUNET_free (sctx->addrs[i++]); 1739 GNUNET_free (sctx->addrs[i++]);
1759 GNUNET_free (sctx->addrs); 1740 GNUNET_free (sctx->addrs);
1760 } 1741 }
1761 GNUNET_free_non_null (sctx->addrlens); 1742 GNUNET_free_non_null (sctx->addrlens);
1762 GNUNET_free_non_null (sctx->v4_denied); 1743 GNUNET_free_non_null (sctx->v4_denied);
1763 GNUNET_free_non_null (sctx->v6_denied); 1744 GNUNET_free_non_null (sctx->v6_denied);