aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-02-23 16:41:30 +0000
committerChristian Grothoff <christian@grothoff.org>2012-02-23 16:41:30 +0000
commit151acb7d8657724bcb2334b636aa3aefc8273ddf (patch)
tree6c1b0edc0ce822528a6691925046bed56b979cb0
parentf3771e363a6ef1e580ea1a67c2498f36ba2ce83e (diff)
downloadgnunet-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--AUTHORS1
-rw-r--r--src/include/gnunet_common.h11
-rw-r--r--src/include/gnunet_crypto_lib.h15
-rw-r--r--src/include/gnunet_server_lib.h66
-rw-r--r--src/util/common_logging.c17
-rw-r--r--src/util/crypto_hash.c5
-rw-r--r--src/util/server.c79
7 files changed, 179 insertions, 15 deletions
diff --git a/AUTHORS b/AUTHORS
index b4edb0e86..61de3fab0 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -31,6 +31,7 @@ Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
31Eric Haumant 31Eric Haumant
32Eric Noack <corvus-gnunet@cybertrench.com> 32Eric Noack <corvus-gnunet@cybertrench.com>
33Felix von Leitner [ diet libc snprintf for win32 ] 33Felix von Leitner [ diet libc snprintf for win32 ]
34Gabor Adam Toth <tg-gnunet@tgbit.net>
34Gerd Knorr <kraxel@bytesex.org> 35Gerd Knorr <kraxel@bytesex.org>
35Glenn McGrath <bug1@iinet.net.au> 36Glenn McGrath <bug1@iinet.net.au>
36Hendrik Pagenhardt <Hendrik.Pagenhardt@gmx.net> 37Hendrik 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);
438const char * 438const char *
439GNUNET_i2s (const struct GNUNET_PeerIdentity *pid); 439GNUNET_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 */
450const char *
451GNUNET_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 */
414int 416int
415GNUNET_CRYPTO_hash_from_string (const char *enc, GNUNET_HashCode * result); 417GNUNET_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 */
245void
246GNUNET_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
636GNUNET_SERVER_mst_destroy (struct GNUNET_SERVER_MessageStreamTokenizer *mst); 644GNUNET_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 */
654typedef 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 */
663typedef 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 */
681typedef 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 */
697void
698GNUNET_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 */
960const char *
961GNUNET_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 */
324int 324int
325GNUNET_CRYPTO_hash_from_string (const char *enc, GNUNET_HashCode * result) 325GNUNET_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
609void
610GNUNET_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
1035void
1036GNUNET_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;