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