aboutsummaryrefslogtreecommitdiff
path: root/src/util
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2016-09-18 20:43:47 +0000
committerChristian Grothoff <christian@grothoff.org>2016-09-18 20:43:47 +0000
commitaf6f9ae173e641a15639b59238bd5e86113a9113 (patch)
tree2b58c7c7a89cc2406a1efd44f7aa5c6b2eaa4e85 /src/util
parentc1ef5b83f7c31c7d6db19d1eb3fa0d1fcef2d595 (diff)
downloadgnunet-af6f9ae173e641a15639b59238bd5e86113a9113.tar.gz
gnunet-af6f9ae173e641a15639b59238bd5e86113a9113.zip
more work on new MST and service logic
Diffstat (limited to 'src/util')
-rw-r--r--src/util/mst.c67
-rw-r--r--src/util/service_new.c318
2 files changed, 278 insertions, 107 deletions
diff --git a/src/util/mst.c b/src/util/mst.c
index 578ba8e04..82a21b880 100644
--- a/src/util/mst.c
+++ b/src/util/mst.c
@@ -144,15 +144,20 @@ do_align:
144 { 144 {
145 /* need to align or need more space */ 145 /* need to align or need more space */
146 mst->pos -= mst->off; 146 mst->pos -= mst->off;
147 memmove (ibuf, &ibuf[mst->off], mst->pos); 147 memmove (ibuf,
148 &ibuf[mst->off],
149 mst->pos);
148 mst->off = 0; 150 mst->off = 0;
149 } 151 }
150 if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader)) 152 if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader))
151 { 153 {
152 delta = 154 delta
153 GNUNET_MIN (sizeof (struct GNUNET_MessageHeader) - 155 = GNUNET_MIN (sizeof (struct GNUNET_MessageHeader)
154 (mst->pos - mst->off), size); 156 - (mst->pos - mst->off),
155 GNUNET_memcpy (&ibuf[mst->pos], buf, delta); 157 size);
158 GNUNET_memcpy (&ibuf[mst->pos],
159 buf,
160 delta);
156 mst->pos += delta; 161 mst->pos += delta;
157 buf += delta; 162 buf += delta;
158 size -= delta; 163 size -= delta;
@@ -178,23 +183,29 @@ do_align:
178 { 183 {
179 /* can get more space by moving */ 184 /* can get more space by moving */
180 mst->pos -= mst->off; 185 mst->pos -= mst->off;
181 memmove (ibuf, &ibuf[mst->off], mst->pos); 186 memmove (ibuf,
187 &ibuf[mst->off],
188 mst->pos);
182 mst->off = 0; 189 mst->off = 0;
183 } 190 }
184 if (mst->curr_buf < want) 191 if (mst->curr_buf < want)
185 { 192 {
186 /* need to get more space by growing buffer */ 193 /* need to get more space by growing buffer */
187 GNUNET_assert (0 == mst->off); 194 GNUNET_assert (0 == mst->off);
188 mst->hdr = GNUNET_realloc (mst->hdr, want); 195 mst->hdr = GNUNET_realloc (mst->hdr,
196 want);
189 ibuf = (char *) mst->hdr; 197 ibuf = (char *) mst->hdr;
190 mst->curr_buf = want; 198 mst->curr_buf = want;
191 } 199 }
192 hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off]; 200 hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
193 if (mst->pos - mst->off < want) 201 if (mst->pos - mst->off < want)
194 { 202 {
195 delta = GNUNET_MIN (want - (mst->pos - mst->off), size); 203 delta = GNUNET_MIN (want - (mst->pos - mst->off),
204 size);
196 GNUNET_assert (mst->pos + delta <= mst->curr_buf); 205 GNUNET_assert (mst->pos + delta <= mst->curr_buf);
197 GNUNET_memcpy (&ibuf[mst->pos], buf, delta); 206 GNUNET_memcpy (&ibuf[mst->pos],
207 buf,
208 delta);
198 mst->pos += delta; 209 mst->pos += delta;
199 buf += delta; 210 buf += delta;
200 size -= delta; 211 size -= delta;
@@ -278,12 +289,15 @@ copy:
278 { 289 {
279 if (size + mst->pos > mst->curr_buf) 290 if (size + mst->pos > mst->curr_buf)
280 { 291 {
281 mst->hdr = GNUNET_realloc (mst->hdr, size + mst->pos); 292 mst->hdr = GNUNET_realloc (mst->hdr,
293 size + mst->pos);
282 ibuf = (char *) mst->hdr; 294 ibuf = (char *) mst->hdr;
283 mst->curr_buf = size + mst->pos; 295 mst->curr_buf = size + mst->pos;
284 } 296 }
285 GNUNET_assert (size + mst->pos <= mst->curr_buf); 297 GNUNET_assert (size + mst->pos <= mst->curr_buf);
286 GNUNET_memcpy (&ibuf[mst->pos], buf, size); 298 GNUNET_memcpy (&ibuf[mst->pos],
299 buf,
300 size);
287 mst->pos += size; 301 mst->pos += size;
288 } 302 }
289 if (purge) 303 if (purge)
@@ -318,8 +332,35 @@ GNUNET_MST_read (struct GNUNET_MessageStreamTokenizer *mst,
318 int purge, 332 int purge,
319 int one_shot) 333 int one_shot)
320{ 334{
321 GNUNET_assert (0); // not implemented 335 ssize_t ret;
322 return GNUNET_SYSERR; 336 size_t left;
337 char *buf;
338
339 left = mst->curr_buf - mst->pos;
340 buf = (char *) mst->hdr;
341 ret = GNUNET_NETWORK_socket_recv (sock,
342 &buf[mst->pos],
343 left);
344 if (-1 == ret)
345 {
346 if ( (EAGAIN == errno) ||
347 (EINTR == errno) )
348 return GNUNET_OK;
349 GNUNET_log_strerror (GNUNET_ERROR_TYPE_INFO,
350 "recv");
351 return GNUNET_SYSERR;
352 }
353 if (0 == ret)
354 {
355 /* other side closed connection, treat as error */
356 return GNUNET_SYSERR;
357 }
358 mst->pos += ret;
359 return GNUNET_MST_from_buffer (mst,
360 NULL,
361 0,
362 purge,
363 one_shot);
323} 364}
324 365
325 366
diff --git a/src/util/service_new.c b/src/util/service_new.c
index 6d17720fd..30fb88f7d 100644
--- a/src/util/service_new.c
+++ b/src/util/service_new.c
@@ -205,9 +205,8 @@ struct GNUNET_SERVICE_Handle
205 int ret; 205 int ret;
206 206
207 /** 207 /**
208 * If GNUNET_YES, consider unknown message types an error where the 208 * If #GNUNET_YES, consider unknown message types an error where the
209 * client is disconnected. 209 * client is disconnected.
210 * FIXME: remove?
211 */ 210 */
212 int require_found; 211 int require_found;
213}; 212};
@@ -247,7 +246,7 @@ struct GNUNET_SERVICE_Client
247 /** 246 /**
248 * Tokenizer we use for processing incoming data. 247 * Tokenizer we use for processing incoming data.
249 */ 248 */
250 struct GNUNET_SERVER_MessageStreamTokenizer *mst; 249 struct GNUNET_MessageStreamTokenizer *mst;
251 250
252 /** 251 /**
253 * Task that warns about missing calls to 252 * Task that warns about missing calls to
@@ -273,6 +272,12 @@ struct GNUNET_SERVICE_Client
273 void *user_context; 272 void *user_context;
274 273
275 /** 274 /**
275 * Time when we last gave a message from this client
276 * to the application.
277 */
278 struct GNUNET_TIME_Absolute warn_start;
279
280 /**
276 * Persist the file handle for this client no matter what happens, 281 * Persist the file handle for this client no matter what happens,
277 * force the OS to close once the process actually dies. Should only 282 * force the OS to close once the process actually dies. Should only
278 * be used in special cases! 283 * be used in special cases!
@@ -287,6 +292,11 @@ struct GNUNET_SERVICE_Client
287 int is_monitor; 292 int is_monitor;
288 293
289 /** 294 /**
295 * Are we waiting for the application to call #GNUNET_SERVICE_client_continue()?
296 */
297 int needs_continue;
298
299 /**
290 * Type of last message processed (for warn_no_receive_done). 300 * Type of last message processed (for warn_no_receive_done).
291 */ 301 */
292 uint16_t warn_type; 302 uint16_t warn_type;
@@ -386,7 +396,9 @@ process_acl4 (struct GNUNET_STRINGS_IPv4NetworkPolicy **ret,
386{ 396{
387 char *opt; 397 char *opt;
388 398
389 if (!GNUNET_CONFIGURATION_have_value (sh->cfg, sh->service_name, option)) 399 if (! GNUNET_CONFIGURATION_have_value (sh->cfg,
400 sh->service_name,
401 option))
390 { 402 {
391 *ret = NULL; 403 *ret = NULL;
392 return GNUNET_OK; 404 return GNUNET_OK;
@@ -394,7 +406,8 @@ process_acl4 (struct GNUNET_STRINGS_IPv4NetworkPolicy **ret,
394 GNUNET_break (GNUNET_OK == 406 GNUNET_break (GNUNET_OK ==
395 GNUNET_CONFIGURATION_get_value_string (sh->cfg, 407 GNUNET_CONFIGURATION_get_value_string (sh->cfg,
396 sh->service_name, 408 sh->service_name,
397 option, &opt)); 409 option,
410 &opt));
398 if (NULL == (*ret = GNUNET_STRINGS_parse_ipv4_policy (opt))) 411 if (NULL == (*ret = GNUNET_STRINGS_parse_ipv4_policy (opt)))
399 { 412 {
400 LOG (GNUNET_ERROR_TYPE_WARNING, 413 LOG (GNUNET_ERROR_TYPE_WARNING,
@@ -426,7 +439,9 @@ process_acl6 (struct GNUNET_STRINGS_IPv6NetworkPolicy **ret,
426{ 439{
427 char *opt; 440 char *opt;
428 441
429 if (!GNUNET_CONFIGURATION_have_value (sh->cfg, sh->service_name, option)) 442 if (! GNUNET_CONFIGURATION_have_value (sh->cfg,
443 sh->service_name,
444 option))
430 { 445 {
431 *ret = NULL; 446 *ret = NULL;
432 return GNUNET_OK; 447 return GNUNET_OK;
@@ -434,12 +449,15 @@ process_acl6 (struct GNUNET_STRINGS_IPv6NetworkPolicy **ret,
434 GNUNET_break (GNUNET_OK == 449 GNUNET_break (GNUNET_OK ==
435 GNUNET_CONFIGURATION_get_value_string (sh->cfg, 450 GNUNET_CONFIGURATION_get_value_string (sh->cfg,
436 sh->service_name, 451 sh->service_name,
437 option, &opt)); 452 option,
453 &opt));
438 if (NULL == (*ret = GNUNET_STRINGS_parse_ipv6_policy (opt))) 454 if (NULL == (*ret = GNUNET_STRINGS_parse_ipv6_policy (opt)))
439 { 455 {
440 LOG (GNUNET_ERROR_TYPE_WARNING, 456 LOG (GNUNET_ERROR_TYPE_WARNING,
441 _("Could not parse IPv6 network specification `%s' for `%s:%s'\n"), 457 _("Could not parse IPv6 network specification `%s' for `%s:%s'\n"),
442 opt, sh->service_name, option); 458 opt,
459 sh->service_name,
460 option);
443 GNUNET_free (opt); 461 GNUNET_free (opt);
444 return GNUNET_SYSERR; 462 return GNUNET_SYSERR;
445 } 463 }
@@ -469,7 +487,9 @@ add_unixpath (struct sockaddr **saddrs,
469 487
470 un = GNUNET_new (struct sockaddr_un); 488 un = GNUNET_new (struct sockaddr_un);
471 un->sun_family = AF_UNIX; 489 un->sun_family = AF_UNIX;
472 strncpy (un->sun_path, unixpath, sizeof (un->sun_path) - 1); 490 strncpy (un->sun_path,
491 unixpath,
492 sizeof (un->sun_path) - 1);
473#ifdef LINUX 493#ifdef LINUX
474 if (GNUNET_YES == abstract) 494 if (GNUNET_YES == abstract)
475 un->sun_path[0] = '\0'; 495 un->sun_path[0] = '\0';
@@ -554,10 +574,10 @@ get_server_addresses (const char *service_name,
554 0); 574 0);
555 if (NULL == desc) 575 if (NULL == desc)
556 { 576 {
557 if ((ENOBUFS == errno) || 577 if ( (ENOBUFS == errno) ||
558 (ENOMEM == errno) || 578 (ENOMEM == errno) ||
559 (ENFILE == errno) || 579 (ENFILE == errno) ||
560 (EACCES == errno)) 580 (EACCES == errno) )
561 { 581 {
562 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, 582 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
563 "socket"); 583 "socket");
@@ -571,7 +591,8 @@ get_server_addresses (const char *service_name,
571 } 591 }
572 else 592 else
573 { 593 {
574 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (desc)); 594 GNUNET_break (GNUNET_OK ==
595 GNUNET_NETWORK_socket_close (desc));
575 desc = NULL; 596 desc = NULL;
576 } 597 }
577 } 598 }
@@ -648,9 +669,9 @@ get_server_addresses (const char *service_name,
648 if (GNUNET_SYSERR == abstract) 669 if (GNUNET_SYSERR == abstract)
649 abstract = GNUNET_NO; 670 abstract = GNUNET_NO;
650#endif 671#endif
651 if ((GNUNET_YES != abstract) 672 if ( (GNUNET_YES != abstract) &&
652 && (GNUNET_OK != 673 (GNUNET_OK !=
653 GNUNET_DISK_directory_create_for_file (unixpath))) 674 GNUNET_DISK_directory_create_for_file (unixpath)) )
654 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, 675 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
655 "mkdir", 676 "mkdir",
656 unixpath); 677 unixpath);
@@ -682,7 +703,8 @@ get_server_addresses (const char *service_name,
682 } 703 }
683 else 704 else
684 { 705 {
685 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (desc)); 706 GNUNET_break (GNUNET_OK ==
707 GNUNET_NETWORK_socket_close (desc));
686 desc = NULL; 708 desc = NULL;
687 } 709 }
688 } 710 }
@@ -994,7 +1016,8 @@ receive_sockets_from_parent (struct GNUNET_SERVICE_Handle *sh)
994 LOG (GNUNET_ERROR_TYPE_ERROR, 1016 LOG (GNUNET_ERROR_TYPE_ERROR,
995 _("Could not access a pre-bound socket, will try to bind myself\n")); 1017 _("Could not access a pre-bound socket, will try to bind myself\n"));
996 for (i = 0; (i < count) && (NULL != lsocks[i]); i++) 1018 for (i = 0; (i < count) && (NULL != lsocks[i]); i++)
997 GNUNET_break (0 == GNUNET_NETWORK_socket_close (lsocks[i])); 1019 GNUNET_break (GNUNET_OK ==
1020 GNUNET_NETWORK_socket_close (lsocks[i]));
998 GNUNET_free (lsocks); 1021 GNUNET_free (lsocks);
999 return NULL; 1022 return NULL;
1000 } 1023 }
@@ -1081,7 +1104,8 @@ open_listen_socket (const struct sockaddr *server_addr,
1081 GNUNET_a2s (server_addr, socklen)); 1104 GNUNET_a2s (server_addr, socklen));
1082 } 1105 }
1083 } 1106 }
1084 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); 1107 GNUNET_break (GNUNET_OK ==
1108 GNUNET_NETWORK_socket_close (sock));
1085 errno = eno; 1109 errno = eno;
1086 return NULL; 1110 return NULL;
1087 } 1111 }
@@ -1090,7 +1114,8 @@ open_listen_socket (const struct sockaddr *server_addr,
1090 { 1114 {
1091 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, 1115 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
1092 "listen"); 1116 "listen");
1093 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); 1117 GNUNET_break (GNUNET_OK ==
1118 GNUNET_NETWORK_socket_close (sock));
1094 errno = 0; 1119 errno = 0;
1095 return NULL; 1120 return NULL;
1096 } 1121 }
@@ -1177,7 +1202,8 @@ setup_service (struct GNUNET_SERVICE_Handle *sh)
1177 (unsigned int) 3 + cnt); 1202 (unsigned int) 3 + cnt);
1178 cnt++; 1203 cnt++;
1179 while (NULL != lsocks[cnt]) 1204 while (NULL != lsocks[cnt])
1180 GNUNET_break (0 == GNUNET_NETWORK_socket_close (lsocks[cnt++])); 1205 GNUNET_break (GNUNET_OK ==
1206 GNUNET_NETWORK_socket_close (lsocks[cnt++]));
1181 GNUNET_free (lsocks); 1207 GNUNET_free (lsocks);
1182 lsocks = NULL; 1208 lsocks = NULL;
1183 break; 1209 break;
@@ -1694,7 +1720,10 @@ shutdown:
1694 struct ServiceListenContext *slc = sh.slc_head; 1720 struct ServiceListenContext *slc = sh.slc_head;
1695 1721
1696 sh.slc_head = slc->next; 1722 sh.slc_head = slc->next;
1697 // FIXME: destroy slc 1723 if (NULL != slc->listen_task)
1724 GNUNET_SCHEDULER_cancel (slc->listen_task);
1725 GNUNET_break (GNUNET_OK ==
1726 GNUNET_NETWORK_socket_close (slc->listen_socket));
1698 GNUNET_free (slc); 1727 GNUNET_free (slc);
1699 } 1728 }
1700 1729
@@ -1778,7 +1807,7 @@ service_mq_cancel (struct GNUNET_MQ_Handle *mq,
1778 * the message queue. 1807 * the message queue.
1779 * Not every message queue implementation supports an error handler. 1808 * Not every message queue implementation supports an error handler.
1780 * 1809 *
1781 * @param cls closure 1810 * @param cls closure with our `struct GNUNET_SERVICE_Client`
1782 * @param error error code 1811 * @param error error code
1783 */ 1812 */
1784static void 1813static void
@@ -1786,8 +1815,35 @@ service_mq_error_handler (void *cls,
1786 enum GNUNET_MQ_Error error) 1815 enum GNUNET_MQ_Error error)
1787{ 1816{
1788 struct GNUNET_SERVICE_Client *client = cls; 1817 struct GNUNET_SERVICE_Client *client = cls;
1818 struct GNUNET_SERVICE_Handle *sh = client->sh;
1789 1819
1790 // FIXME! 1820 if ( (GNUNET_MQ_ERROR_NO_MATCH == error) &&
1821 (GNUNET_NO == sh->require_found) )
1822 return; /* ignore error */
1823 GNUNET_SERVICE_client_drop (client);
1824}
1825
1826
1827/**
1828 * Task run to warn about missing calls to #GNUNET_SERVICE_client_continue().
1829 *
1830 * @param cls our `struct GNUNET_SERVICE_Client *` to process more requests from
1831 */
1832static void
1833warn_no_client_continue (void *cls)
1834{
1835 struct GNUNET_SERVICE_Client *client = cls;
1836
1837 GNUNET_break (0 != client->warn_type); /* type should never be 0 here, as we don't use 0 */
1838 client->warn_task
1839 = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
1840 &warn_no_client_continue,
1841 client);
1842 LOG (GNUNET_ERROR_TYPE_WARNING,
1843 _("Processing code for message of type %u did not call `GNUNET_SERVICE_client_continue' after %s\n"),
1844 (unsigned int) client->warn_type,
1845 GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (client->warn_start),
1846 GNUNET_YES));
1791} 1847}
1792 1848
1793 1849
@@ -1795,21 +1851,27 @@ service_mq_error_handler (void *cls,
1795 * Functions with this signature are called whenever a 1851 * Functions with this signature are called whenever a
1796 * complete message is received by the tokenizer for a client. 1852 * complete message is received by the tokenizer for a client.
1797 * 1853 *
1798 * Do not call #GNUNET_SERVER_mst_destroy() from within 1854 * Do not call #GNUNET_MST_destroy() from within
1799 * the scope of this callback. 1855 * the scope of this callback.
1800 * 1856 *
1801 * @param cls closure with the `struct GNUNET_SERVICE_Client *` 1857 * @param cls closure with the `struct GNUNET_SERVICE_Client *`
1802 * @param client_cls closure with the `struct GNUNET_SERVICE_Client *`
1803 * @param message the actual message 1858 * @param message the actual message
1804 * @return #GNUNET_OK on success (always) 1859 * @return #GNUNET_OK on success (always)
1805 */ 1860 */
1806static int 1861static int
1807service_client_mst_cb (void *cls, 1862service_client_mst_cb (void *cls,
1808 void *client_cls,
1809 const struct GNUNET_MessageHeader *message) 1863 const struct GNUNET_MessageHeader *message)
1810{ 1864{
1811 struct GNUNET_SERVICE_Client *client = cls; 1865 struct GNUNET_SERVICE_Client *client = cls;
1812 1866
1867 GNUNET_assert (GNUNET_NO == client->needs_continue);
1868 client->needs_continue = GNUNET_YES;
1869 client->warn_type = ntohs (message->type);
1870 client->warn_start = GNUNET_TIME_absolute_get ();
1871 client->warn_task
1872 = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
1873 &warn_no_client_continue,
1874 client);
1813 GNUNET_MQ_inject_message (client->mq, 1875 GNUNET_MQ_inject_message (client->mq,
1814 message); 1876 message);
1815 return GNUNET_OK; 1877 return GNUNET_OK;
@@ -1826,10 +1888,31 @@ static void
1826service_client_recv (void *cls) 1888service_client_recv (void *cls)
1827{ 1889{
1828 struct GNUNET_SERVICE_Client *client = cls; 1890 struct GNUNET_SERVICE_Client *client = cls;
1891 int ret;
1829 1892
1830 // FIXME: read into buffer, pass to MST, then client->mq inject! 1893 client->recv_task = NULL;
1831 // FIXME: revise MST API to avoid the memcpy! 1894 ret = GNUNET_MST_read (client->mst,
1832 // i.e.: GNUNET_MST_read (client->sock); 1895 client->sock,
1896 GNUNET_NO,
1897 GNUNET_YES);
1898 if (GNUNET_SYSERR == ret)
1899 {
1900 GNUNET_break (0);
1901 GNUNET_SERVICE_client_drop (client);
1902 return;
1903 }
1904 if (GNUNET_NO == ret)
1905 return; /* more messages in buffer, wait for application
1906 to be done processing */
1907 GNUNET_assert (GNUNET_OK == ret);
1908 if (GNUNET_YES == client->needs_continue)
1909 return;
1910 /* MST needs more data, re-schedule read job */
1911 client->recv_task
1912 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
1913 client->sock,
1914 &service_client_recv,
1915 client);
1833} 1916}
1834 1917
1835 1918
@@ -1859,8 +1942,8 @@ start_client (struct GNUNET_SERVICE_Handle *sh,
1859 sh->handlers, 1942 sh->handlers,
1860 &service_mq_error_handler, 1943 &service_mq_error_handler,
1861 client); 1944 client);
1862 client->mst = GNUNET_SERVER_mst_create (&service_client_mst_cb, 1945 client->mst = GNUNET_MST_create (&service_client_mst_cb,
1863 client); 1946 client);
1864 client->user_context = sh->connect_cb (sh->cb_cls, 1947 client->user_context = sh->connect_cb (sh->cb_cls,
1865 client, 1948 client,
1866 client->mq); 1949 client->mq);
@@ -1955,69 +2038,70 @@ accept_client (void *cls)
1955 2038
1956 slc->listen_task = NULL; 2039 slc->listen_task = NULL;
1957 while (1) 2040 while (1)
2041 {
2042 struct GNUNET_NETWORK_Handle *sock;
2043 const struct sockaddr_in *v4;
2044 const struct sockaddr_in6 *v6;
2045 struct sockaddr_storage sa;
2046 socklen_t addrlen;
2047 int ok;
2048
2049 addrlen = sizeof (sa);
2050 sock = GNUNET_NETWORK_socket_accept (slc->listen_socket,
2051 (struct sockaddr *) &sa,
2052 &addrlen);
2053 if (NULL == sock)
2054 break;
2055 switch (sa.ss_family)
1958 { 2056 {
1959 struct GNUNET_NETWORK_Handle *sock; 2057 case AF_INET:
1960 const struct sockaddr_in *v4; 2058 GNUNET_assert (addrlen == sizeof (struct sockaddr_in));
1961 const struct sockaddr_in6 *v6; 2059 v4 = (const struct sockaddr_in *) &sa;
1962 struct sockaddr_storage sa; 2060 ok = ( ( (NULL == sh->v4_allowed) ||
1963 socklen_t addrlen; 2061 (check_ipv4_listed (sh->v4_allowed,
1964 int ok; 2062 &v4->sin_addr))) &&
1965 2063 ( (NULL == sh->v4_denied) ||
1966 addrlen = sizeof (sa); 2064 (! check_ipv4_listed (sh->v4_denied,
1967 sock = GNUNET_NETWORK_socket_accept (slc->listen_socket, 2065 &v4->sin_addr)) ) );
1968 (struct sockaddr *) &sa, 2066 break;
1969 &addrlen); 2067 case AF_INET6:
1970 if (NULL == sock) 2068 GNUNET_assert (addrlen == sizeof (struct sockaddr_in6));
1971 break; 2069 v6 = (const struct sockaddr_in6 *) &sa;
1972 switch (sa.ss_family) 2070 ok = ( ( (NULL == sh->v6_allowed) ||
1973 { 2071 (check_ipv6_listed (sh->v6_allowed,
1974 case AF_INET: 2072 &v6->sin6_addr))) &&
1975 GNUNET_assert (addrlen == sizeof (struct sockaddr_in)); 2073 ( (NULL == sh->v6_denied) ||
1976 v4 = (const struct sockaddr_in *) &sa; 2074 (! check_ipv6_listed (sh->v6_denied,
1977 ok = ( ( (NULL == sh->v4_allowed) || 2075 &v6->sin6_addr)) ) );
1978 (check_ipv4_listed (sh->v4_allowed, 2076 break;
1979 &v4->sin_addr))) &&
1980 ( (NULL == sh->v4_denied) ||
1981 (! check_ipv4_listed (sh->v4_denied,
1982 &v4->sin_addr)) ) );
1983 break;
1984 case AF_INET6:
1985 GNUNET_assert (addrlen == sizeof (struct sockaddr_in6));
1986 v6 = (const struct sockaddr_in6 *) &sa;
1987 ok = ( ( (NULL == sh->v6_allowed) ||
1988 (check_ipv6_listed (sh->v6_allowed,
1989 &v6->sin6_addr))) &&
1990 ( (NULL == sh->v6_denied) ||
1991 (! check_ipv6_listed (sh->v6_denied,
1992 &v6->sin6_addr)) ) );
1993 break;
1994#ifndef WINDOWS 2077#ifndef WINDOWS
1995 case AF_UNIX: 2078 case AF_UNIX:
1996 ok = GNUNET_OK; /* controlled using file-system ACL now */ 2079 ok = GNUNET_OK; /* controlled using file-system ACL now */
1997 break; 2080 break;
1998#endif 2081#endif
1999 default: 2082 default:
2000 LOG (GNUNET_ERROR_TYPE_WARNING, 2083 LOG (GNUNET_ERROR_TYPE_WARNING,
2001 _("Unknown address family %d\n"), 2084 _("Unknown address family %d\n"),
2002 sa.ss_family); 2085 sa.ss_family);
2003 return; 2086 return;
2004 } 2087 }
2005 if (! ok) 2088 if (! ok)
2006 { 2089 {
2007 LOG (GNUNET_ERROR_TYPE_DEBUG,
2008 "Service rejected incoming connection from %s due to policy.\n",
2009 GNUNET_a2s ((const struct sockaddr *) &sa,
2010 addrlen));
2011 GNUNET_NETWORK_socket_close (sock);
2012 continue;
2013 }
2014 LOG (GNUNET_ERROR_TYPE_DEBUG, 2090 LOG (GNUNET_ERROR_TYPE_DEBUG,
2015 "Service accepted incoming connection from %s.\n", 2091 "Service rejected incoming connection from %s due to policy.\n",
2016 GNUNET_a2s ((const struct sockaddr *) &sa, 2092 GNUNET_a2s ((const struct sockaddr *) &sa,
2017 addrlen)); 2093 addrlen));
2018 start_client (slc->sh, 2094 GNUNET_break (GNUNET_OK ==
2019 sock); 2095 GNUNET_NETWORK_socket_close (sock));
2096 continue;
2020 } 2097 }
2098 LOG (GNUNET_ERROR_TYPE_DEBUG,
2099 "Service accepted incoming connection from %s.\n",
2100 GNUNET_a2s ((const struct sockaddr *) &sa,
2101 addrlen));
2102 start_client (slc->sh,
2103 sock);
2104 }
2021 slc->listen_task 2105 slc->listen_task
2022 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, 2106 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
2023 slc->listen_socket, 2107 slc->listen_socket,
@@ -2049,6 +2133,42 @@ GNUNET_SERVICE_resume (struct GNUNET_SERVICE_Handle *sh)
2049 2133
2050 2134
2051/** 2135/**
2136 * Task run to resume receiving data from the client after
2137 * the client called #GNUNET_SERVICE_client_continue().
2138 *
2139 * @param cls our `struct GNUNET_SERVICE_Client`
2140 */
2141static void
2142resume_client_receive (void *cls)
2143{
2144 struct GNUNET_SERVICE_Client *c = cls;
2145 int ret;
2146
2147 c->recv_task = NULL;
2148 /* first, check if there is still something in the buffer */
2149 ret = GNUNET_MST_next (c->mst,
2150 GNUNET_YES);
2151 if (GNUNET_SYSERR == ret)
2152 {
2153 GNUNET_break (0);
2154 GNUNET_SERVICE_client_drop (c);
2155 return;
2156 }
2157 if (GNUNET_NO == ret)
2158 return; /* done processing, wait for more later */
2159 GNUNET_assert (GNUNET_OK == ret);
2160 if (GNUNET_YES == c->needs_continue)
2161 return; /* #GNUNET_MST_next() did give a message to the client */
2162 /* need to receive more data from the network first */
2163 c->recv_task
2164 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
2165 c->sock,
2166 &service_client_recv,
2167 c);
2168}
2169
2170
2171/**
2052 * Continue receiving further messages from the given client. 2172 * Continue receiving further messages from the given client.
2053 * Must be called after each message received. 2173 * Must be called after each message received.
2054 * 2174 *
@@ -2057,7 +2177,16 @@ GNUNET_SERVICE_resume (struct GNUNET_SERVICE_Handle *sh)
2057void 2177void
2058GNUNET_SERVICE_client_continue (struct GNUNET_SERVICE_Client *c) 2178GNUNET_SERVICE_client_continue (struct GNUNET_SERVICE_Client *c)
2059{ 2179{
2060 GNUNET_break (0); // not implemented 2180 GNUNET_assert (GNUNET_YES == c->needs_continue);
2181 GNUNET_assert (NULL == c->recv_task);
2182 c->needs_continue = GNUNET_NO;
2183 if (NULL != c->warn_task)
2184 {
2185 GNUNET_SCHEDULER_cancel (c->warn_task);
2186 c->warn_task = NULL;
2187 }
2188 c->recv_task = GNUNET_SCHEDULER_add_now (&resume_client_receive,
2189 c);
2061} 2190}
2062 2191
2063 2192
@@ -2117,11 +2246,12 @@ GNUNET_SERVICE_client_drop (struct GNUNET_SERVICE_Client *c)
2117 GNUNET_SCHEDULER_cancel (c->send_task); 2246 GNUNET_SCHEDULER_cancel (c->send_task);
2118 c->send_task = NULL; 2247 c->send_task = NULL;
2119 } 2248 }
2120 GNUNET_SERVER_mst_destroy (c->mst); 2249 GNUNET_MST_destroy (c->mst);
2121 GNUNET_MQ_destroy (c->mq); 2250 GNUNET_MQ_destroy (c->mq);
2122 if (GNUNET_NO == c->persist) 2251 if (GNUNET_NO == c->persist)
2123 { 2252 {
2124 GNUNET_NETWORK_socket_close (c->sock); 2253 GNUNET_break (GNUNET_OK ==
2254 GNUNET_NETWORK_socket_close (c->sock));
2125 } 2255 }
2126 else 2256 else
2127 { 2257 {