diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-02-23 16:41:30 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-02-23 16:41:30 +0000 |
commit | 151acb7d8657724bcb2334b636aa3aefc8273ddf (patch) | |
tree | 6c1b0edc0ce822528a6691925046bed56b979cb0 | |
parent | f3771e363a6ef1e580ea1a67c2498f36ba2ce83e (diff) | |
download | gnunet-151acb7d8657724bcb2334b636aa3aefc8273ddf.tar.gz gnunet-151acb7d8657724bcb2334b636aa3aefc8273ddf.zip |
TG: attached are the following patches for GNUnet:
- 1: added GNUNET_i2s_full - full variant of GNUNET_i2s
- 2: GNUNET_CRYPTO_hash_from_string2 with additional length parameter,
useful to prevent an additional strlen call when the caller already knows
the length
- 3: custom mst callbacks for the server, enables using the server with a
custom parser
- 4: added GNUNET_SERVER_client_set_finish_pending_write - enables changing the
server behavior to finish pending writes when closing the connection
Best regards,
Gabor Adam Toth
-rw-r--r-- | AUTHORS | 1 | ||||
-rw-r--r-- | src/include/gnunet_common.h | 11 | ||||
-rw-r--r-- | src/include/gnunet_crypto_lib.h | 15 | ||||
-rw-r--r-- | src/include/gnunet_server_lib.h | 66 | ||||
-rw-r--r-- | src/util/common_logging.c | 17 | ||||
-rw-r--r-- | src/util/crypto_hash.c | 5 | ||||
-rw-r--r-- | src/util/server.c | 79 |
7 files changed, 179 insertions, 15 deletions
@@ -31,6 +31,7 @@ Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de> | |||
31 | Eric Haumant | 31 | Eric Haumant |
32 | Eric Noack <corvus-gnunet@cybertrench.com> | 32 | Eric Noack <corvus-gnunet@cybertrench.com> |
33 | Felix von Leitner [ diet libc snprintf for win32 ] | 33 | Felix von Leitner [ diet libc snprintf for win32 ] |
34 | Gabor Adam Toth <tg-gnunet@tgbit.net> | ||
34 | Gerd Knorr <kraxel@bytesex.org> | 35 | Gerd Knorr <kraxel@bytesex.org> |
35 | Glenn McGrath <bug1@iinet.net.au> | 36 | Glenn McGrath <bug1@iinet.net.au> |
36 | Hendrik Pagenhardt <Hendrik.Pagenhardt@gmx.net> | 37 | Hendrik Pagenhardt <Hendrik.Pagenhardt@gmx.net> |
diff --git a/src/include/gnunet_common.h b/src/include/gnunet_common.h index 487bd32da..3221ad868 100644 --- a/src/include/gnunet_common.h +++ b/src/include/gnunet_common.h | |||
@@ -438,6 +438,17 @@ GNUNET_h2s_full (const GNUNET_HashCode * hc); | |||
438 | const char * | 438 | const char * |
439 | GNUNET_i2s (const struct GNUNET_PeerIdentity *pid); | 439 | GNUNET_i2s (const struct GNUNET_PeerIdentity *pid); |
440 | 440 | ||
441 | /** | ||
442 | * Convert a peer identity to a string (for printing debug messages). | ||
443 | * This is one of the very few calls in the entire API that is | ||
444 | * NOT reentrant! | ||
445 | * | ||
446 | * @param pid the peer identity | ||
447 | * @return string form of the pid; will be overwritten by next | ||
448 | * call to GNUNET_i2s. | ||
449 | */ | ||
450 | const char * | ||
451 | GNUNET_i2s_full (const struct GNUNET_PeerIdentity *pid); | ||
441 | 452 | ||
442 | /** | 453 | /** |
443 | * Convert a "struct sockaddr*" (IPv4 or IPv6 address) to a string | 454 | * Convert a "struct sockaddr*" (IPv4 or IPv6 address) to a string |
diff --git a/src/include/gnunet_crypto_lib.h b/src/include/gnunet_crypto_lib.h index 75aabe75f..6e37266a2 100644 --- a/src/include/gnunet_crypto_lib.h +++ b/src/include/gnunet_crypto_lib.h | |||
@@ -407,12 +407,25 @@ GNUNET_CRYPTO_hash_to_enc (const GNUNET_HashCode * block, | |||
407 | 407 | ||
408 | /** | 408 | /** |
409 | * Convert ASCII encoding back to GNUNET_CRYPTO_hash | 409 | * Convert ASCII encoding back to GNUNET_CRYPTO_hash |
410 | * | ||
410 | * @param enc the encoding | 411 | * @param enc the encoding |
412 | * @param enclen number of characters in 'enc' (without 0-terminator, which can be missing) | ||
411 | * @param result where to store the GNUNET_CRYPTO_hash code | 413 | * @param result where to store the GNUNET_CRYPTO_hash code |
412 | * @return GNUNET_OK on success, GNUNET_SYSERR if result has the wrong encoding | 414 | * @return GNUNET_OK on success, GNUNET_SYSERR if result has the wrong encoding |
413 | */ | 415 | */ |
414 | int | 416 | int |
415 | GNUNET_CRYPTO_hash_from_string (const char *enc, GNUNET_HashCode * result); | 417 | GNUNET_CRYPTO_hash_from_string2 (const char *enc, size_t enclen, |
418 | GNUNET_HashCode * result); | ||
419 | |||
420 | |||
421 | /** | ||
422 | * Convert ASCII encoding back to GNUNET_CRYPTO_hash | ||
423 | * @param enc the encoding | ||
424 | * @param result where to store the GNUNET_CRYPTO_hash code | ||
425 | * @return GNUNET_OK on success, GNUNET_SYSERR if result has the wrong encoding | ||
426 | */ | ||
427 | #define GNUNET_CRYPTO_hash_from_string(enc, result) \ | ||
428 | GNUNET_CRYPTO_hash_from_string2 (enc, strlen(enc), result) | ||
416 | 429 | ||
417 | 430 | ||
418 | /** | 431 | /** |
diff --git a/src/include/gnunet_server_lib.h b/src/include/gnunet_server_lib.h index 2856fd838..7fb8ae76c 100644 --- a/src/include/gnunet_server_lib.h +++ b/src/include/gnunet_server_lib.h | |||
@@ -240,6 +240,14 @@ GNUNET_SERVER_client_set_timeout (struct GNUNET_SERVER_Client *client, | |||
240 | 240 | ||
241 | 241 | ||
242 | /** | 242 | /** |
243 | * Set if a client should finish a pending write when disconnecting. | ||
244 | */ | ||
245 | void | ||
246 | GNUNET_SERVER_client_set_finish_pending_write (struct GNUNET_SERVER_Client *client, | ||
247 | int finish); | ||
248 | |||
249 | |||
250 | /** | ||
243 | * Disable the warning the server issues if a message is not acknowledged | 251 | * Disable the warning the server issues if a message is not acknowledged |
244 | * in a timely fashion. Use this call if a client is intentionally delayed | 252 | * in a timely fashion. Use this call if a client is intentionally delayed |
245 | * for a while. Only applies to the current message. | 253 | * for a while. Only applies to the current message. |
@@ -636,6 +644,64 @@ void | |||
636 | GNUNET_SERVER_mst_destroy (struct GNUNET_SERVER_MessageStreamTokenizer *mst); | 644 | GNUNET_SERVER_mst_destroy (struct GNUNET_SERVER_MessageStreamTokenizer *mst); |
637 | 645 | ||
638 | 646 | ||
647 | /** | ||
648 | * Signature of a function to create a custom tokenizer. | ||
649 | * | ||
650 | * @param cls closure from 'GNUNET_SERVER_set_callbacks' | ||
651 | * @param client handle to client the tokenzier will be used for | ||
652 | * @return handle to custom tokenizer ('mst') | ||
653 | */ | ||
654 | typedef void* (*GNUNET_SERVER_MstCreateCallback) (void *cls, | ||
655 | struct GNUNET_SERVER_Client *client); | ||
656 | |||
657 | /** | ||
658 | * Signature of a function to destroy a custom tokenizer. | ||
659 | * | ||
660 | * @param cls closure from 'GNUNET_SERVER_set_callbacks' | ||
661 | * @param mst custom tokenizer handle | ||
662 | */ | ||
663 | typedef void (*GNUNET_SERVER_MstDestroyCallback) (void *cls, void *mst); | ||
664 | |||
665 | /** | ||
666 | * Signature of a function to destroy a custom tokenizer. | ||
667 | * | ||
668 | * @param cls closure from 'GNUNET_SERVER_set_callbacks' | ||
669 | * @param mst custom tokenizer handle | ||
670 | * @param client_identity ID of client for which this is a buffer, | ||
671 | * can be NULL (will be passed back to 'cb') | ||
672 | * @param buf input data to add | ||
673 | * @param size number of bytes in buf | ||
674 | * @param purge should any excess bytes in the buffer be discarded | ||
675 | * (i.e. for packet-based services like UDP) | ||
676 | * @param one_shot only call callback once, keep rest of message in buffer | ||
677 | * @return GNUNET_OK if we are done processing (need more data) | ||
678 | * GNUNET_NO if one_shot was set and we have another message ready | ||
679 | * GNUNET_SYSERR if the data stream is corrupt | ||
680 | */ | ||
681 | typedef int (*GNUNET_SERVER_MstReceiveCallback) (void *cls, void *mst, | ||
682 | struct GNUNET_SERVER_Client *client, | ||
683 | const char *buf, size_t size, | ||
684 | int purge, int one_shot); | ||
685 | |||
686 | |||
687 | /** | ||
688 | * Change functions used by the server to tokenize the message stream. | ||
689 | * (very rarely used). | ||
690 | * | ||
691 | * @param server server to modify | ||
692 | * @param create new tokenizer initialization function | ||
693 | * @param destroy new tokenizer destruction function | ||
694 | * @param receive new tokenizer receive function | ||
695 | * @param cls closure for 'create', 'receive', 'destroy' | ||
696 | */ | ||
697 | void | ||
698 | GNUNET_SERVER_set_callbacks (struct GNUNET_SERVER_Handle *server, | ||
699 | GNUNET_SERVER_MstCreateCallback create, | ||
700 | GNUNET_SERVER_MstDestroyCallback destroy, | ||
701 | GNUNET_SERVER_MstReceiveCallback receive, | ||
702 | void *cls); | ||
703 | |||
704 | |||
639 | #if 0 /* keep Emacsens' auto-indent happy */ | 705 | #if 0 /* keep Emacsens' auto-indent happy */ |
640 | { | 706 | { |
641 | #endif | 707 | #endif |
diff --git a/src/util/common_logging.c b/src/util/common_logging.c index 59de96226..e19aa8c7c 100644 --- a/src/util/common_logging.c +++ b/src/util/common_logging.c | |||
@@ -948,6 +948,23 @@ GNUNET_i2s (const struct GNUNET_PeerIdentity *pid) | |||
948 | return (const char *) ret.encoding; | 948 | return (const char *) ret.encoding; |
949 | } | 949 | } |
950 | 950 | ||
951 | /** | ||
952 | * Convert a peer identity to a string (for printing debug messages). | ||
953 | * This is one of the very few calls in the entire API that is | ||
954 | * NOT reentrant! | ||
955 | * | ||
956 | * @param pid the peer identity | ||
957 | * @return string form of the pid; will be overwritten by next | ||
958 | * call to GNUNET_i2s. | ||
959 | */ | ||
960 | const char * | ||
961 | GNUNET_i2s_full (const struct GNUNET_PeerIdentity *pid) | ||
962 | { | ||
963 | static struct GNUNET_CRYPTO_HashAsciiEncoded ret; | ||
964 | |||
965 | GNUNET_CRYPTO_hash_to_enc (&pid->hashPubKey, &ret); | ||
966 | return (const char *) ret.encoding; | ||
967 | } | ||
951 | 968 | ||
952 | 969 | ||
953 | /** | 970 | /** |
diff --git a/src/util/crypto_hash.c b/src/util/crypto_hash.c index 0350df545..976c59992 100644 --- a/src/util/crypto_hash.c +++ b/src/util/crypto_hash.c | |||
@@ -322,7 +322,8 @@ GNUNET_CRYPTO_hash_to_enc (const GNUNET_HashCode * block, | |||
322 | * @return GNUNET_OK on success, GNUNET_SYSERR if result has the wrong encoding | 322 | * @return GNUNET_OK on success, GNUNET_SYSERR if result has the wrong encoding |
323 | */ | 323 | */ |
324 | int | 324 | int |
325 | GNUNET_CRYPTO_hash_from_string (const char *enc, GNUNET_HashCode * result) | 325 | GNUNET_CRYPTO_hash_from_string2 (const char *enc, size_t enclen, |
326 | GNUNET_HashCode * result) | ||
326 | { | 327 | { |
327 | unsigned int rpos; | 328 | unsigned int rpos; |
328 | unsigned int wpos; | 329 | unsigned int wpos; |
@@ -330,7 +331,7 @@ GNUNET_CRYPTO_hash_from_string (const char *enc, GNUNET_HashCode * result) | |||
330 | unsigned int vbit; | 331 | unsigned int vbit; |
331 | int ret; | 332 | int ret; |
332 | 333 | ||
333 | if (strlen (enc) != sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1) | 334 | if (enclen != sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1) |
334 | return GNUNET_SYSERR; | 335 | return GNUNET_SYSERR; |
335 | 336 | ||
336 | vbit = 2; /* padding! */ | 337 | vbit = 2; /* padding! */ |
diff --git a/src/util/server.c b/src/util/server.c index 6f1b8cdb4..24804d2d2 100644 --- a/src/util/server.c +++ b/src/util/server.c | |||
@@ -140,6 +140,10 @@ struct GNUNET_SERVER_Handle | |||
140 | */ | 140 | */ |
141 | int clients_ignore_shutdown; | 141 | int clients_ignore_shutdown; |
142 | 142 | ||
143 | GNUNET_SERVER_MstCreateCallback mst_create; | ||
144 | GNUNET_SERVER_MstDestroyCallback mst_destroy; | ||
145 | GNUNET_SERVER_MstReceiveCallback mst_receive; | ||
146 | void *mst_cls; | ||
143 | }; | 147 | }; |
144 | 148 | ||
145 | 149 | ||
@@ -157,7 +161,7 @@ struct GNUNET_SERVER_Client | |||
157 | /** | 161 | /** |
158 | * Processing of incoming data. | 162 | * Processing of incoming data. |
159 | */ | 163 | */ |
160 | struct GNUNET_SERVER_MessageStreamTokenizer *mst; | 164 | void *mst; |
161 | 165 | ||
162 | /** | 166 | /** |
163 | * Server that this client belongs to. | 167 | * Server that this client belongs to. |
@@ -243,6 +247,11 @@ struct GNUNET_SERVER_Client | |||
243 | int receive_pending; | 247 | int receive_pending; |
244 | 248 | ||
245 | /** | 249 | /** |
250 | * Finish pending write when disconnecting? | ||
251 | */ | ||
252 | int finish_pending_write; | ||
253 | |||
254 | /** | ||
246 | * Persist the file handle for this client no matter what happens, | 255 | * Persist the file handle for this client no matter what happens, |
247 | * force the OS to close once the process actually dies. Should only | 256 | * force the OS to close once the process actually dies. Should only |
248 | * be used in special cases! | 257 | * be used in special cases! |
@@ -597,6 +606,20 @@ GNUNET_SERVER_add_handlers (struct GNUNET_SERVER_Handle *server, | |||
597 | } | 606 | } |
598 | 607 | ||
599 | 608 | ||
609 | void | ||
610 | GNUNET_SERVER_set_callbacks (struct GNUNET_SERVER_Handle *server, | ||
611 | GNUNET_SERVER_MstCreateCallback create, | ||
612 | GNUNET_SERVER_MstDestroyCallback destroy, | ||
613 | GNUNET_SERVER_MstReceiveCallback receive, | ||
614 | void *cls) | ||
615 | { | ||
616 | server->mst_create = create; | ||
617 | server->mst_destroy = destroy; | ||
618 | server->mst_receive = receive; | ||
619 | server->mst_cls = cls; | ||
620 | } | ||
621 | |||
622 | |||
600 | /** | 623 | /** |
601 | * Task run to warn about missing calls to 'GNUNET_SERVER_receive_done'. | 624 | * Task run to warn about missing calls to 'GNUNET_SERVER_receive_done'. |
602 | * | 625 | * |
@@ -776,9 +799,14 @@ process_mst (struct GNUNET_SERVER_Client *client, int ret) | |||
776 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 799 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
777 | "Server processes additional messages instantly.\n"); | 800 | "Server processes additional messages instantly.\n"); |
778 | #endif | 801 | #endif |
779 | ret = | 802 | if (client->server->mst_receive != NULL) |
780 | GNUNET_SERVER_mst_receive (client->mst, client, NULL, 0, GNUNET_NO, | 803 | ret = |
781 | GNUNET_YES); | 804 | client->server->mst_receive (client->server->mst_cls, client->mst, |
805 | client, NULL, 0, GNUNET_NO, GNUNET_YES); | ||
806 | else | ||
807 | ret = | ||
808 | GNUNET_SERVER_mst_receive (client->mst, client, NULL, 0, GNUNET_NO, | ||
809 | GNUNET_YES); | ||
782 | } | 810 | } |
783 | #if DEBUG_SERVER | 811 | #if DEBUG_SERVER |
784 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 812 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
@@ -857,9 +885,16 @@ process_incoming (void *cls, const void *buf, size_t available, | |||
857 | #endif | 885 | #endif |
858 | GNUNET_SERVER_client_keep (client); | 886 | GNUNET_SERVER_client_keep (client); |
859 | client->last_activity = now; | 887 | client->last_activity = now; |
860 | ret = | 888 | |
861 | GNUNET_SERVER_mst_receive (client->mst, client, buf, available, GNUNET_NO, | 889 | if (server->mst_receive != NULL) |
862 | GNUNET_YES); | 890 | ret = |
891 | client->server->mst_receive (client->server->mst_cls, client->mst, | ||
892 | client, buf, available, GNUNET_NO, GNUNET_YES); | ||
893 | else | ||
894 | ret = | ||
895 | GNUNET_SERVER_mst_receive (client->mst, client, buf, available, GNUNET_NO, | ||
896 | GNUNET_YES); | ||
897 | |||
863 | process_mst (client, ret); | 898 | process_mst (client, ret); |
864 | } | 899 | } |
865 | 900 | ||
@@ -966,6 +1001,14 @@ GNUNET_SERVER_connect_socket (struct GNUNET_SERVER_Handle *server, | |||
966 | client->receive_pending = GNUNET_YES; | 1001 | client->receive_pending = GNUNET_YES; |
967 | client->callback = NULL; | 1002 | client->callback = NULL; |
968 | client->callback_cls = NULL; | 1003 | client->callback_cls = NULL; |
1004 | |||
1005 | if (server->mst_create != NULL) | ||
1006 | client->mst = | ||
1007 | server->mst_create (server->mst_cls, client); | ||
1008 | else | ||
1009 | client->mst = | ||
1010 | GNUNET_SERVER_mst_create (&client_message_tokenizer_callback, server); | ||
1011 | |||
969 | GNUNET_CONNECTION_receive (client->connection, | 1012 | GNUNET_CONNECTION_receive (client->connection, |
970 | GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, | 1013 | GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, |
971 | client->idle_timeout, &process_incoming, client); | 1014 | client->idle_timeout, &process_incoming, client); |
@@ -989,6 +1032,14 @@ GNUNET_SERVER_client_set_timeout (struct GNUNET_SERVER_Client *client, | |||
989 | } | 1032 | } |
990 | 1033 | ||
991 | 1034 | ||
1035 | void | ||
1036 | GNUNET_SERVER_client_set_finish_pending_write (struct GNUNET_SERVER_Client *client, | ||
1037 | int finish) | ||
1038 | { | ||
1039 | client->finish_pending_write = finish; | ||
1040 | } | ||
1041 | |||
1042 | |||
992 | /** | 1043 | /** |
993 | * Notify the server that the given client handle should | 1044 | * Notify the server that the given client handle should |
994 | * be kept (keeps the connection up if possible, increments | 1045 | * be kept (keeps the connection up if possible, increments |
@@ -1137,10 +1188,9 @@ GNUNET_SERVER_client_disconnect (struct GNUNET_SERVER_Client *client) | |||
1137 | } | 1188 | } |
1138 | 1189 | ||
1139 | rc = client->reference_count; | 1190 | rc = client->reference_count; |
1140 | if (client->server != NULL) | 1191 | if (client->shutdown_now != GNUNET_YES) |
1141 | { | 1192 | { |
1142 | server = client->server; | 1193 | server = client->server; |
1143 | client->server = NULL; | ||
1144 | client->shutdown_now = GNUNET_YES; | 1194 | client->shutdown_now = GNUNET_YES; |
1145 | prev = NULL; | 1195 | prev = NULL; |
1146 | pos = server->clients; | 1196 | pos = server->clients; |
@@ -1190,8 +1240,13 @@ GNUNET_SERVER_client_disconnect (struct GNUNET_SERVER_Client *client) | |||
1190 | 1240 | ||
1191 | if (client->persist == GNUNET_YES) | 1241 | if (client->persist == GNUNET_YES) |
1192 | GNUNET_CONNECTION_persist_ (client->connection); | 1242 | GNUNET_CONNECTION_persist_ (client->connection); |
1193 | GNUNET_CONNECTION_destroy (client->connection, GNUNET_NO); | 1243 | GNUNET_CONNECTION_destroy (client->connection, client->finish_pending_write); |
1194 | GNUNET_SERVER_mst_destroy (client->mst); | 1244 | |
1245 | if (client->server->mst_destroy != NULL) | ||
1246 | client->server->mst_destroy (client->server->mst_cls, client->mst); | ||
1247 | else | ||
1248 | GNUNET_SERVER_mst_destroy (client->mst); | ||
1249 | |||
1195 | GNUNET_free (client); | 1250 | GNUNET_free (client); |
1196 | } | 1251 | } |
1197 | 1252 | ||
@@ -1326,7 +1381,7 @@ GNUNET_SERVER_receive_done (struct GNUNET_SERVER_Client *client, int success) | |||
1326 | #endif | 1381 | #endif |
1327 | return; | 1382 | return; |
1328 | } | 1383 | } |
1329 | if (client->server == NULL) | 1384 | if ((client->server == NULL) || (GNUNET_YES == client->shutdown_now)) |
1330 | { | 1385 | { |
1331 | GNUNET_SERVER_client_disconnect (client); | 1386 | GNUNET_SERVER_client_disconnect (client); |
1332 | return; | 1387 | return; |