diff options
author | Christian Grothoff <christian@grothoff.org> | 2010-04-21 08:14:23 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2010-04-21 08:14:23 +0000 |
commit | b6818796397f2a15992ce759a0005dc848e19e23 (patch) | |
tree | 4d5a957253497cf3d9bda00751f08570bea88907 /src/transport | |
parent | 6f7541fa5956928c2b8ec10aa075e2aac12c3235 (diff) | |
download | gnunet-b6818796397f2a15992ce759a0005dc848e19e23.tar.gz gnunet-b6818796397f2a15992ce759a0005dc848e19e23.zip |
towards implementing blacklisting
Diffstat (limited to 'src/transport')
-rw-r--r-- | src/transport/gnunet-service-transport.c | 320 |
1 files changed, 226 insertions, 94 deletions
diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c index a30595d02..7396d0ca3 100644 --- a/src/transport/gnunet-service-transport.c +++ b/src/transport/gnunet-service-transport.c | |||
@@ -67,6 +67,11 @@ | |||
67 | #define MAX_PENDING 128 | 67 | #define MAX_PENDING 128 |
68 | 68 | ||
69 | /** | 69 | /** |
70 | * Size of the per-transport blacklist hash maps. | ||
71 | */ | ||
72 | #define TRANSPORT_BLACKLIST_HT_SIZE 16 | ||
73 | |||
74 | /** | ||
70 | * How often should we try to reconnect to a peer using a particular | 75 | * How often should we try to reconnect to a peer using a particular |
71 | * transport plugin before giving up? Note that the plugin may be | 76 | * transport plugin before giving up? Note that the plugin may be |
72 | * added back to the list after PLUGIN_RETRY_FREQUENCY expires. | 77 | * added back to the list after PLUGIN_RETRY_FREQUENCY expires. |
@@ -944,26 +949,24 @@ is_blacklisted (const struct GNUNET_PeerIdentity *peer, struct TransportPlugin * | |||
944 | return GNUNET_NO; | 949 | return GNUNET_NO; |
945 | } | 950 | } |
946 | 951 | ||
952 | |||
947 | static void | 953 | static void |
948 | add_peer_to_blacklist (struct GNUNET_PeerIdentity *peer, char *transport_name) | 954 | add_peer_to_blacklist (struct GNUNET_PeerIdentity *peer, char *transport_name) |
949 | { | 955 | { |
950 | struct TransportPlugin *plugin; | 956 | struct TransportPlugin *plugin; |
951 | 957 | ||
952 | plugin = find_transport(transport_name); | 958 | plugin = find_transport(transport_name); |
953 | |||
954 | if (plugin == NULL) /* Nothing to do */ | 959 | if (plugin == NULL) /* Nothing to do */ |
955 | return; | 960 | return; |
956 | 961 | if (plugin->blacklist == NULL) | |
957 | if (plugin->blacklist == NULL) | 962 | plugin->blacklist = GNUNET_CONTAINER_multihashmap_create(TRANSPORT_BLACKLIST_HT_SIZE); |
958 | { | ||
959 | plugin->blacklist = GNUNET_CONTAINER_multihashmap_create(100); /* FIXME: estimated number of peers or what? */ | ||
960 | } | ||
961 | |||
962 | GNUNET_assert(plugin->blacklist != NULL); | 963 | GNUNET_assert(plugin->blacklist != NULL); |
963 | 964 | GNUNET_CONTAINER_multihashmap_put(plugin->blacklist, &peer->hashPubKey, | |
964 | GNUNET_CONTAINER_multihashmap_put(plugin->blacklist, &peer->hashPubKey, NULL, GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE); | 965 | NULL, |
966 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE); | ||
965 | } | 967 | } |
966 | 968 | ||
969 | |||
967 | /** | 970 | /** |
968 | * Read the blacklist file, containing transport:peer entries. | 971 | * Read the blacklist file, containing transport:peer entries. |
969 | * Provided the transport is loaded, set up hashmap with these | 972 | * Provided the transport is loaded, set up hashmap with these |
@@ -1014,6 +1017,7 @@ read_blacklist_file (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1014 | GNUNET_free (fn); | 1017 | GNUNET_free (fn); |
1015 | return; | 1018 | return; |
1016 | } | 1019 | } |
1020 | /* FIXME: use mmap */ | ||
1017 | data = GNUNET_malloc_large (frstat.st_size); | 1021 | data = GNUNET_malloc_large (frstat.st_size); |
1018 | if (frstat.st_size != | 1022 | if (frstat.st_size != |
1019 | GNUNET_DISK_fn_read (fn, data, frstat.st_size)) | 1023 | GNUNET_DISK_fn_read (fn, data, frstat.st_size)) |
@@ -1122,9 +1126,9 @@ read_blacklist_file (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1122 | } | 1126 | } |
1123 | GNUNET_free (data); | 1127 | GNUNET_free (data); |
1124 | GNUNET_free (fn); | 1128 | GNUNET_free (fn); |
1125 | |||
1126 | } | 1129 | } |
1127 | 1130 | ||
1131 | |||
1128 | /** | 1132 | /** |
1129 | * Function called to notify a client about the socket being ready to | 1133 | * Function called to notify a client about the socket being ready to |
1130 | * queue more data. "buf" will be NULL and "size" zero if the socket | 1134 | * queue more data. "buf" will be NULL and "size" zero if the socket |
@@ -2512,13 +2516,16 @@ add_hello_for_peer (void *cls, | |||
2512 | 2516 | ||
2513 | /** | 2517 | /** |
2514 | * Create a fresh entry in our neighbour list for the given peer. | 2518 | * Create a fresh entry in our neighbour list for the given peer. |
2515 | * Will try to transmit our current HELLO to the new neighbour. | 2519 | * Will try to transmit our current HELLO to the new neighbour. |
2520 | * Do not call this function directly, use 'setup_peer_check_blacklist. | ||
2516 | * | 2521 | * |
2517 | * @param peer the peer for which we create the entry | 2522 | * @param peer the peer for which we create the entry |
2523 | * @param do_hello should we schedule transmitting a HELLO | ||
2518 | * @return the new neighbour list entry | 2524 | * @return the new neighbour list entry |
2519 | */ | 2525 | */ |
2520 | static struct NeighbourList * | 2526 | static struct NeighbourList * |
2521 | setup_new_neighbour (const struct GNUNET_PeerIdentity *peer) | 2527 | setup_new_neighbour (const struct GNUNET_PeerIdentity *peer, |
2528 | int do_hello) | ||
2522 | { | 2529 | { |
2523 | struct NeighbourList *n; | 2530 | struct NeighbourList *n; |
2524 | struct TransportPlugin *tp; | 2531 | struct TransportPlugin *tp; |
@@ -2558,18 +2565,65 @@ setup_new_neighbour (const struct GNUNET_PeerIdentity *peer) | |||
2558 | n->timeout_task = GNUNET_SCHEDULER_add_delayed (sched, | 2565 | n->timeout_task = GNUNET_SCHEDULER_add_delayed (sched, |
2559 | GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, | 2566 | GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, |
2560 | &neighbour_timeout_task, n); | 2567 | &neighbour_timeout_task, n); |
2561 | n->piter = GNUNET_PEERINFO_iterate (cfg, sched, peer, | 2568 | if (do_hello) |
2562 | 0, GNUNET_TIME_UNIT_FOREVER_REL, | 2569 | { |
2563 | &add_hello_for_peer, n); | 2570 | n->piter = GNUNET_PEERINFO_iterate (cfg, sched, peer, |
2564 | transmit_to_peer (NULL, NULL, 0, | 2571 | 0, GNUNET_TIME_UNIT_FOREVER_REL, |
2565 | HELLO_ADDRESS_EXPIRATION, | 2572 | &add_hello_for_peer, n); |
2566 | (const char *) our_hello, GNUNET_HELLO_size(our_hello), | 2573 | transmit_to_peer (NULL, NULL, 0, |
2567 | GNUNET_NO, n); | 2574 | HELLO_ADDRESS_EXPIRATION, |
2575 | (const char *) our_hello, GNUNET_HELLO_size(our_hello), | ||
2576 | GNUNET_NO, n); | ||
2577 | } | ||
2568 | return n; | 2578 | return n; |
2569 | } | 2579 | } |
2570 | 2580 | ||
2571 | 2581 | ||
2572 | /** | 2582 | /** |
2583 | * Function called after we have checked if communicating | ||
2584 | * with a given peer is acceptable. | ||
2585 | * | ||
2586 | * @param cls closure | ||
2587 | * @param n NULL if communication is not acceptable | ||
2588 | */ | ||
2589 | typedef void (*SetupContinuation)(void *cls, | ||
2590 | struct NeighbourList *n); | ||
2591 | |||
2592 | |||
2593 | |||
2594 | /** | ||
2595 | * Obtain a 'struct NeighbourList' for the given peer. If such an entry | ||
2596 | * does not yet exist, check the blacklist. If the blacklist says creating | ||
2597 | * one is acceptable, create one and call the continuation; otherwise | ||
2598 | * call the continuation with NULL. | ||
2599 | * | ||
2600 | * @param peer peer to setup or look up a struct NeighbourList for | ||
2601 | * @param do_hello should we also schedule sending our HELLO to the peer | ||
2602 | * if this is a new record | ||
2603 | * @param cont function to call with the 'struct NeigbhbourList*' | ||
2604 | * @param cont_cls closure for cont | ||
2605 | */ | ||
2606 | static void | ||
2607 | setup_peer_check_blacklist (const struct GNUNET_PeerIdentity *peer, | ||
2608 | int do_hello, | ||
2609 | SetupContinuation cont, | ||
2610 | void *cont_cls) | ||
2611 | { | ||
2612 | struct NeighbourList *n; | ||
2613 | |||
2614 | n = find_neighbour(peer); | ||
2615 | if (n != NULL) | ||
2616 | { | ||
2617 | cont (cont_cls, n); | ||
2618 | return; | ||
2619 | } | ||
2620 | /* FIXME: do actual blacklist checking here... */ | ||
2621 | cont (cont_cls, | ||
2622 | setup_new_neighbour (peer, do_hello)); | ||
2623 | } | ||
2624 | |||
2625 | |||
2626 | /** | ||
2573 | * Send periodic PING messages to a give foreign address. | 2627 | * Send periodic PING messages to a give foreign address. |
2574 | * | 2628 | * |
2575 | * @param cls our 'struct PeriodicValidationContext*' | 2629 | * @param cls our 'struct PeriodicValidationContext*' |
@@ -2997,6 +3051,79 @@ handle_pong (void *cls, const struct GNUNET_MessageHeader *message, | |||
2997 | 3051 | ||
2998 | 3052 | ||
2999 | /** | 3053 | /** |
3054 | * Try to validate a neighbour's address by sending him our HELLO and a PING. | ||
3055 | * | ||
3056 | * @param cls the 'struct ValidationEntry*' | ||
3057 | * @param neighbour neighbour to validate, NULL if validation failed | ||
3058 | */ | ||
3059 | static void | ||
3060 | transmit_hello_and_ping (void *cls, | ||
3061 | struct NeighbourList *neighbour) | ||
3062 | { | ||
3063 | struct ValidationEntry *va = cls; | ||
3064 | struct ForeignAddressList *peer_address; | ||
3065 | struct TransportPingMessage ping; | ||
3066 | uint16_t hello_size; | ||
3067 | size_t tsize; | ||
3068 | char * message_buf; | ||
3069 | |||
3070 | if (neighbour == NULL) | ||
3071 | { | ||
3072 | /* FIXME: stats... */ | ||
3073 | GNUNET_free (va->transport_name); | ||
3074 | GNUNET_free (va); | ||
3075 | return; | ||
3076 | } | ||
3077 | neighbour->publicKey = va->publicKey; | ||
3078 | neighbour->public_key_valid = GNUNET_YES; | ||
3079 | peer_address = add_peer_address (neighbour, | ||
3080 | va->transport_name, NULL, | ||
3081 | (const void*) &va[1], | ||
3082 | va->addrlen); | ||
3083 | if (peer_address == NULL) | ||
3084 | { | ||
3085 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
3086 | "Failed to add peer `%4s' for plugin `%s'\n", | ||
3087 | GNUNET_i2s (&neighbour->id), | ||
3088 | va->transport_name); | ||
3089 | GNUNET_free (va->transport_name); | ||
3090 | GNUNET_free (va); | ||
3091 | return; | ||
3092 | } | ||
3093 | hello_size = GNUNET_HELLO_size(our_hello); | ||
3094 | tsize = sizeof(struct TransportPingMessage) + hello_size; | ||
3095 | message_buf = GNUNET_malloc(tsize); | ||
3096 | ping.challenge = htonl(va->challenge); | ||
3097 | ping.header.size = htons(sizeof(struct TransportPingMessage)); | ||
3098 | ping.header.type = htons(GNUNET_MESSAGE_TYPE_TRANSPORT_PING); | ||
3099 | memcpy(&ping.target, &neighbour->id, sizeof(struct GNUNET_PeerIdentity)); | ||
3100 | memcpy(message_buf, our_hello, hello_size); | ||
3101 | memcpy(&message_buf[hello_size], | ||
3102 | &ping, | ||
3103 | sizeof(struct TransportPingMessage)); | ||
3104 | #if DEBUG_TRANSPORT | ||
3105 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
3106 | "Performing validation of address `%s' via `%s' for peer `%4s' sending `%s' (%u bytes) and `%s' (%u bytes)\n", | ||
3107 | GNUNET_a2s ((const void*) &va[1], va->addrlen), | ||
3108 | va->transport_name, | ||
3109 | GNUNET_i2s (&neighbour->id), | ||
3110 | "HELLO", hello_size, | ||
3111 | "PING", sizeof (struct TransportPingMessage)); | ||
3112 | #endif | ||
3113 | GNUNET_STATISTICS_update (stats, | ||
3114 | gettext_noop ("# PING messages sent for initial validation"), | ||
3115 | 1, | ||
3116 | GNUNET_NO); | ||
3117 | transmit_to_peer (NULL, peer_address, | ||
3118 | GNUNET_SCHEDULER_PRIORITY_DEFAULT, | ||
3119 | HELLO_VERIFICATION_TIMEOUT, | ||
3120 | message_buf, tsize, | ||
3121 | GNUNET_YES, neighbour); | ||
3122 | GNUNET_free(message_buf); | ||
3123 | } | ||
3124 | |||
3125 | |||
3126 | /** | ||
3000 | * Check if the given address is already being validated; if not, | 3127 | * Check if the given address is already being validated; if not, |
3001 | * append the given address to the list of entries that are being be | 3128 | * append the given address to the list of entries that are being be |
3002 | * validated and initiate validation. | 3129 | * validated and initiate validation. |
@@ -3018,14 +3145,8 @@ run_validation (void *cls, | |||
3018 | struct GNUNET_PeerIdentity id; | 3145 | struct GNUNET_PeerIdentity id; |
3019 | struct TransportPlugin *tp; | 3146 | struct TransportPlugin *tp; |
3020 | struct ValidationEntry *va; | 3147 | struct ValidationEntry *va; |
3021 | struct NeighbourList *neighbour; | ||
3022 | struct ForeignAddressList *peer_address; | ||
3023 | struct TransportPingMessage ping; | ||
3024 | struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pk; | 3148 | struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pk; |
3025 | struct CheckAddressExistsClosure caec; | 3149 | struct CheckAddressExistsClosure caec; |
3026 | char * message_buf; | ||
3027 | uint16_t hello_size; | ||
3028 | size_t tsize; | ||
3029 | 3150 | ||
3030 | GNUNET_assert (addr != NULL); | 3151 | GNUNET_assert (addr != NULL); |
3031 | GNUNET_STATISTICS_update (stats, | 3152 | GNUNET_STATISTICS_update (stats, |
@@ -3106,49 +3227,9 @@ run_validation (void *cls, | |||
3106 | &id.hashPubKey, | 3227 | &id.hashPubKey, |
3107 | va, | 3228 | va, |
3108 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | 3229 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); |
3109 | neighbour = find_neighbour(&id); | 3230 | setup_peer_check_blacklist (&id, GNUNET_NO, |
3110 | if (neighbour == NULL) | 3231 | &transmit_hello_and_ping, |
3111 | neighbour = setup_new_neighbour(&id); | 3232 | va); |
3112 | neighbour->publicKey = va->publicKey; | ||
3113 | neighbour->public_key_valid = GNUNET_YES; | ||
3114 | peer_address = add_peer_address (neighbour, tname, NULL, addr, addrlen); | ||
3115 | if (peer_address == NULL) | ||
3116 | { | ||
3117 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
3118 | "Attempted to add peer `%4s' for plugin `%s'\n", | ||
3119 | GNUNET_i2s (&id), tname); | ||
3120 | } | ||
3121 | GNUNET_assert(peer_address != NULL); | ||
3122 | hello_size = GNUNET_HELLO_size(our_hello); | ||
3123 | tsize = sizeof(struct TransportPingMessage) + hello_size; | ||
3124 | message_buf = GNUNET_malloc(tsize); | ||
3125 | ping.challenge = htonl(va->challenge); | ||
3126 | ping.header.size = htons(sizeof(struct TransportPingMessage)); | ||
3127 | ping.header.type = htons(GNUNET_MESSAGE_TYPE_TRANSPORT_PING); | ||
3128 | memcpy(&ping.target, &id, sizeof(struct GNUNET_PeerIdentity)); | ||
3129 | memcpy(message_buf, our_hello, hello_size); | ||
3130 | memcpy(&message_buf[hello_size], | ||
3131 | &ping, | ||
3132 | sizeof(struct TransportPingMessage)); | ||
3133 | #if DEBUG_TRANSPORT | ||
3134 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
3135 | "Performing validation of address `%s' via `%s' for peer `%4s' sending `%s' (%u bytes) and `%s' (%u bytes)\n", | ||
3136 | GNUNET_a2s (addr, addrlen), | ||
3137 | tname, | ||
3138 | GNUNET_i2s (&id), | ||
3139 | "HELLO", hello_size, | ||
3140 | "PING", sizeof (struct TransportPingMessage)); | ||
3141 | #endif | ||
3142 | GNUNET_STATISTICS_update (stats, | ||
3143 | gettext_noop ("# PING messages sent for initial validation"), | ||
3144 | 1, | ||
3145 | GNUNET_NO); | ||
3146 | transmit_to_peer (NULL, peer_address, | ||
3147 | GNUNET_SCHEDULER_PRIORITY_DEFAULT, | ||
3148 | HELLO_VERIFICATION_TIMEOUT, | ||
3149 | message_buf, tsize, | ||
3150 | GNUNET_YES, neighbour); | ||
3151 | GNUNET_free(message_buf); | ||
3152 | return GNUNET_OK; | 3233 | return GNUNET_OK; |
3153 | } | 3234 | } |
3154 | 3235 | ||
@@ -3627,12 +3708,12 @@ plugin_env_receive (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
3627 | struct NeighbourList *n; | 3708 | struct NeighbourList *n; |
3628 | struct GNUNET_TIME_Relative ret; | 3709 | struct GNUNET_TIME_Relative ret; |
3629 | 3710 | ||
3630 | if (is_blacklisted(peer, plugin)) | 3711 | if (is_blacklisted (peer, plugin)) |
3631 | return GNUNET_TIME_UNIT_FOREVER_REL; | 3712 | return GNUNET_TIME_UNIT_FOREVER_REL; |
3632 | 3713 | ||
3633 | n = find_neighbour (peer); | 3714 | n = find_neighbour (peer); |
3634 | if (n == NULL) | 3715 | if (n == NULL) |
3635 | n = setup_new_neighbour (peer); | 3716 | n = setup_new_neighbour (peer, GNUNET_YES); |
3636 | service_context = n->plugins; | 3717 | service_context = n->plugins; |
3637 | while ((service_context != NULL) && (plugin != service_context->plugin)) | 3718 | while ((service_context != NULL) && (plugin != service_context->plugin)) |
3638 | service_context = service_context->next; | 3719 | service_context = service_context->next; |
@@ -3820,6 +3901,64 @@ handle_hello (void *cls, | |||
3820 | 3901 | ||
3821 | 3902 | ||
3822 | /** | 3903 | /** |
3904 | * Closure for 'transmit_client_message'; followed by | ||
3905 | * 'msize' bytes of the actual message. | ||
3906 | */ | ||
3907 | struct TransmitClientMessageContext | ||
3908 | { | ||
3909 | /** | ||
3910 | * Client on whom's behalf we are sending. | ||
3911 | */ | ||
3912 | struct GNUNET_SERVER_Client *client; | ||
3913 | |||
3914 | /** | ||
3915 | * Timeout for the transmission. | ||
3916 | */ | ||
3917 | struct GNUNET_TIME_Absolute timeout; | ||
3918 | |||
3919 | /** | ||
3920 | * Message priority. | ||
3921 | */ | ||
3922 | uint32_t priority; | ||
3923 | |||
3924 | /** | ||
3925 | * Size of the message in bytes. | ||
3926 | */ | ||
3927 | uint16_t msize; | ||
3928 | }; | ||
3929 | |||
3930 | |||
3931 | /** | ||
3932 | * Schedule transmission of a message we got from a client to a peer. | ||
3933 | * | ||
3934 | * @param cls the 'struct TransmitClientMessageContext*' | ||
3935 | * @param n destination, or NULL on error (in that case, drop the message) | ||
3936 | */ | ||
3937 | static void | ||
3938 | transmit_client_message (void *cls, | ||
3939 | struct NeighbourList *n) | ||
3940 | { | ||
3941 | struct TransmitClientMessageContext *tcmc = cls; | ||
3942 | struct TransportClient *tc; | ||
3943 | |||
3944 | tc = clients; | ||
3945 | while ((tc != NULL) && (tc->client != tcmc->client)) | ||
3946 | tc = tc->next; | ||
3947 | |||
3948 | if (n != NULL) | ||
3949 | { | ||
3950 | transmit_to_peer (tc, NULL, tcmc->priority, | ||
3951 | GNUNET_TIME_absolute_get_remaining (tcmc->timeout), | ||
3952 | (char *)&tcmc[1], | ||
3953 | tcmc->msize, GNUNET_NO, n); | ||
3954 | } | ||
3955 | GNUNET_SERVER_receive_done (tcmc->client, GNUNET_OK); | ||
3956 | GNUNET_SERVER_client_drop (tcmc->client); | ||
3957 | GNUNET_free (tcmc); | ||
3958 | } | ||
3959 | |||
3960 | |||
3961 | /** | ||
3823 | * Handle SEND-message. | 3962 | * Handle SEND-message. |
3824 | * | 3963 | * |
3825 | * @param cls closure (always NULL) | 3964 | * @param cls closure (always NULL) |
@@ -3831,10 +3970,9 @@ handle_send (void *cls, | |||
3831 | struct GNUNET_SERVER_Client *client, | 3970 | struct GNUNET_SERVER_Client *client, |
3832 | const struct GNUNET_MessageHeader *message) | 3971 | const struct GNUNET_MessageHeader *message) |
3833 | { | 3972 | { |
3834 | struct TransportClient *tc; | ||
3835 | struct NeighbourList *n; | ||
3836 | const struct OutboundMessage *obm; | 3973 | const struct OutboundMessage *obm; |
3837 | const struct GNUNET_MessageHeader *obmm; | 3974 | const struct GNUNET_MessageHeader *obmm; |
3975 | struct TransmitClientMessageContext *tcmc; | ||
3838 | uint16_t size; | 3976 | uint16_t size; |
3839 | uint16_t msize; | 3977 | uint16_t msize; |
3840 | 3978 | ||
@@ -3851,37 +3989,31 @@ handle_send (void *cls, | |||
3851 | size, | 3989 | size, |
3852 | GNUNET_NO); | 3990 | GNUNET_NO); |
3853 | obm = (const struct OutboundMessage *) message; | 3991 | obm = (const struct OutboundMessage *) message; |
3992 | obmm = (const struct GNUNET_MessageHeader *) &obm[1]; | ||
3993 | msize = ntohs (obmm->size); | ||
3854 | #if DEBUG_TRANSPORT | 3994 | #if DEBUG_TRANSPORT |
3855 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 3995 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
3856 | "Received `%s' request from client with target `%4s'\n", | 3996 | "Received `%s' request from client with target `%4s' and message of type %u and size %u\n", |
3857 | "SEND", GNUNET_i2s (&obm->peer)); | 3997 | "SEND", GNUNET_i2s (&obm->peer), |
3998 | ntohs (obmm->type), | ||
3999 | msize); | ||
3858 | #endif | 4000 | #endif |
3859 | obmm = (const struct GNUNET_MessageHeader *) &obm[1]; | ||
3860 | msize = ntohs (obmm->size); | ||
3861 | if (size != msize + sizeof (struct OutboundMessage)) | 4001 | if (size != msize + sizeof (struct OutboundMessage)) |
3862 | { | 4002 | { |
3863 | GNUNET_break (0); | 4003 | GNUNET_break (0); |
3864 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 4004 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); |
3865 | return; | 4005 | return; |
3866 | } | 4006 | } |
3867 | n = find_neighbour (&obm->peer); | 4007 | tcmc = GNUNET_malloc (sizeof (struct TransmitClientMessageContext) + msize); |
3868 | if (n == NULL) | 4008 | tcmc->client = client; |
3869 | n = setup_new_neighbour (&obm->peer); | 4009 | tcmc->priority = ntohl (obm->priority); |
3870 | tc = clients; | 4010 | tcmc->timeout = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_ntoh (obm->timeout)); |
3871 | while ((tc != NULL) && (tc->client != client)) | 4011 | tcmc->msize = msize; |
3872 | tc = tc->next; | 4012 | memcpy (&tcmc[1], obmm, msize); |
3873 | 4013 | GNUNET_SERVER_client_keep (client); | |
3874 | #if DEBUG_TRANSPORT | 4014 | setup_peer_check_blacklist (&obm->peer, GNUNET_YES, |
3875 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 4015 | &transmit_client_message, |
3876 | "Client asked to transmit %u-byte message of type %u to `%4s'\n", | 4016 | tcmc); |
3877 | ntohs (obmm->size), | ||
3878 | ntohs (obmm->type), GNUNET_i2s (&obm->peer)); | ||
3879 | #endif | ||
3880 | transmit_to_peer (tc, NULL, ntohl (obm->priority), | ||
3881 | GNUNET_TIME_relative_ntoh (obm->timeout), | ||
3882 | (char *)obmm, | ||
3883 | ntohs (obmm->size), GNUNET_NO, n); | ||
3884 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
3885 | } | 4017 | } |
3886 | 4018 | ||
3887 | 4019 | ||