diff options
-rw-r--r-- | src/transport/gnunet-service-transport.c | 27 | ||||
-rw-r--r-- | src/transport/plugin_transport.h | 6 | ||||
-rw-r--r-- | src/transport/plugin_transport_tcp.c | 119 | ||||
-rw-r--r-- | src/transport/transport_api.c | 5 |
4 files changed, 107 insertions, 50 deletions
diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c index 7cb5869e9..ad4aec8ca 100644 --- a/src/transport/gnunet-service-transport.c +++ b/src/transport/gnunet-service-transport.c | |||
@@ -873,6 +873,10 @@ transmit_send_continuation (void *cls, | |||
873 | rl->transmit_ready = GNUNET_YES; | 873 | rl->transmit_ready = GNUNET_YES; |
874 | if (mq->client != NULL) | 874 | if (mq->client != NULL) |
875 | { | 875 | { |
876 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
877 | "Notifying client %p about failed transission to peer `%4s'.\n", | ||
878 | mq->client, | ||
879 | GNUNET_i2s(target)); | ||
876 | send_ok_msg.header.size = htons (sizeof (send_ok_msg)); | 880 | send_ok_msg.header.size = htons (sizeof (send_ok_msg)); |
877 | send_ok_msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_OK); | 881 | send_ok_msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_OK); |
878 | send_ok_msg.success = htonl (result); | 882 | send_ok_msg.success = htonl (result); |
@@ -885,6 +889,8 @@ transmit_send_continuation (void *cls, | |||
885 | another message (if available) */ | 889 | another message (if available) */ |
886 | if (result == GNUNET_OK) | 890 | if (result == GNUNET_OK) |
887 | try_transmission_to_peer (n); | 891 | try_transmission_to_peer (n); |
892 | else | ||
893 | disconnect_neighbour (n); | ||
888 | } | 894 | } |
889 | 895 | ||
890 | 896 | ||
@@ -1867,13 +1873,15 @@ disconnect_neighbour (struct NeighbourList *n) | |||
1867 | /* notify all clients about disconnect */ | 1873 | /* notify all clients about disconnect */ |
1868 | notify_clients_disconnect (&n->id); | 1874 | notify_clients_disconnect (&n->id); |
1869 | 1875 | ||
1870 | /* clean up all plugins, cancel connections & pending transmissions */ | 1876 | /* clean up all plugins, cancel connections and pending transmissions */ |
1871 | while (NULL != (rpos = n->plugins)) | 1877 | while (NULL != (rpos = n->plugins)) |
1872 | { | 1878 | { |
1873 | n->plugins = rpos->next; | 1879 | n->plugins = rpos->next; |
1874 | GNUNET_assert (rpos->neighbour == n); | 1880 | GNUNET_assert (rpos->neighbour == n); |
1875 | rpos->plugin->api->cancel (rpos->plugin->api->cls, | 1881 | rpos->plugin->api->cancel (rpos->plugin->api->cls, |
1876 | rpos->plugin_handle, rpos, &n->id); | 1882 | rpos->plugin_handle, |
1883 | rpos, | ||
1884 | &n->id); | ||
1877 | GNUNET_free (rpos); | 1885 | GNUNET_free (rpos); |
1878 | } | 1886 | } |
1879 | 1887 | ||
@@ -2040,14 +2048,19 @@ plugin_env_receive (void *cls, | |||
2040 | } | 2048 | } |
2041 | if (message == NULL) | 2049 | if (message == NULL) |
2042 | { | 2050 | { |
2051 | #if DEBUG_TRANSPORT | ||
2052 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, | ||
2053 | "Receive failed from `%4s', triggering disconnect\n", | ||
2054 | GNUNET_i2s(&n->id)); | ||
2055 | #endif | ||
2056 | /* TODO: call stats */ | ||
2057 | disconnect_neighbour (n); | ||
2043 | if ((service_context != NULL) && | 2058 | if ((service_context != NULL) && |
2044 | (service_context->plugin_handle == plugin_context)) | 2059 | (service_context->plugin_handle == plugin_context)) |
2045 | { | 2060 | { |
2046 | service_context->connected = GNUNET_NO; | 2061 | service_context->connected = GNUNET_NO; |
2047 | service_context->plugin_handle = NULL; | 2062 | service_context->plugin_handle = NULL; |
2048 | } | 2063 | } |
2049 | /* TODO: call stats */ | ||
2050 | disconnect_neighbour (n); | ||
2051 | return NULL; | 2064 | return NULL; |
2052 | } | 2065 | } |
2053 | #if DEBUG_TRANSPORT | 2066 | #if DEBUG_TRANSPORT |
@@ -2362,8 +2375,10 @@ handle_try_connect (void *cls, | |||
2362 | tcm = (const struct TryConnectMessage *) message; | 2375 | tcm = (const struct TryConnectMessage *) message; |
2363 | #if DEBUG_TRANSPORT | 2376 | #if DEBUG_TRANSPORT |
2364 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2377 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2365 | "Received `%s' request from client asking to connect to `%4s'\n", | 2378 | "Received `%s' request from client %p asking to connect to `%4s'\n", |
2366 | "TRY_CONNECT", GNUNET_i2s (&tcm->peer)); | 2379 | "TRY_CONNECT", |
2380 | client, | ||
2381 | GNUNET_i2s (&tcm->peer)); | ||
2367 | #endif | 2382 | #endif |
2368 | if (NULL == find_neighbour (&tcm->peer)) | 2383 | if (NULL == find_neighbour (&tcm->peer)) |
2369 | setup_new_neighbour (&tcm->peer); | 2384 | setup_new_neighbour (&tcm->peer); |
diff --git a/src/transport/plugin_transport.h b/src/transport/plugin_transport.h index 10fad4886..2a2e90d2a 100644 --- a/src/transport/plugin_transport.h +++ b/src/transport/plugin_transport.h | |||
@@ -349,7 +349,11 @@ typedef void * | |||
349 | * @param plugin_context value we were asked to pass to this plugin | 349 | * @param plugin_context value we were asked to pass to this plugin |
350 | * to respond to the given peer (use is optional, | 350 | * to respond to the given peer (use is optional, |
351 | * but may speed up processing), can be NULL (if | 351 | * but may speed up processing), can be NULL (if |
352 | * NULL was returned from the transmit function) | 352 | * NULL was returned from the transmit function); note |
353 | * that use of NULL is dangerous since then this call may | ||
354 | * cancel any session with the target peer (including | ||
355 | * HELLO validation sessions), which is likely not what | ||
356 | * is intended. | ||
353 | * @param service_context must correspond to the service context | 357 | * @param service_context must correspond to the service context |
354 | * of the corresponding Transmit call; the plugin should | 358 | * of the corresponding Transmit call; the plugin should |
355 | * not cancel a send call made with a different service | 359 | * not cancel a send call made with a different service |
diff --git a/src/transport/plugin_transport_tcp.c b/src/transport/plugin_transport_tcp.c index 57bd5175e..b5b4547cc 100644 --- a/src/transport/plugin_transport_tcp.c +++ b/src/transport/plugin_transport_tcp.c | |||
@@ -216,7 +216,6 @@ struct PendingMessage | |||
216 | */ | 216 | */ |
217 | struct GNUNET_MessageHeader *msg; | 217 | struct GNUNET_MessageHeader *msg; |
218 | 218 | ||
219 | |||
220 | /** | 219 | /** |
221 | * Continuation function to call once the message | 220 | * Continuation function to call once the message |
222 | * has been sent. Can be NULL if there is no | 221 | * has been sent. Can be NULL if there is no |
@@ -540,10 +539,17 @@ do_transmit (void *cls, size_t size, void *buf) | |||
540 | while (NULL != (pm = session->pending_messages)) | 539 | while (NULL != (pm = session->pending_messages)) |
541 | { | 540 | { |
542 | session->pending_messages = pm->next; | 541 | session->pending_messages = pm->next; |
542 | #if DEBUG_TCP | ||
543 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | ||
544 | "tcp", | ||
545 | "Failed to transmit message of type %u to `%4s'.\n", | ||
546 | ntohs(pm->msg->type), | ||
547 | GNUNET_i2s(&session->target)); | ||
548 | #endif | ||
543 | if (pm->transmit_cont != NULL) | 549 | if (pm->transmit_cont != NULL) |
544 | pm->transmit_cont (pm->transmit_cont_cls, | 550 | pm->transmit_cont (pm->transmit_cont_cls, |
545 | session->service_context, | 551 | session->service_context, |
546 | &session->target, GNUNET_SYSERR); | 552 | &session->target, GNUNET_SYSERR); |
547 | GNUNET_free (pm); | 553 | GNUNET_free (pm); |
548 | } | 554 | } |
549 | return 0; | 555 | return 0; |
@@ -787,16 +793,6 @@ disconnect_session (struct Session *session) | |||
787 | else | 793 | else |
788 | prev->next = session->next; | 794 | prev->next = session->next; |
789 | /* clean up state */ | 795 | /* clean up state */ |
790 | if (session->client != NULL) | ||
791 | { | ||
792 | #if DEBUG_TCP | ||
793 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | ||
794 | "tcp", | ||
795 | "Disconnecting from client address %p\n", session->client); | ||
796 | #endif | ||
797 | GNUNET_SERVER_client_drop (session->client); | ||
798 | session->client = NULL; | ||
799 | } | ||
800 | if (session->transmit_handle != NULL) | 796 | if (session->transmit_handle != NULL) |
801 | { | 797 | { |
802 | GNUNET_NETWORK_notify_transmit_ready_cancel (session->transmit_handle); | 798 | GNUNET_NETWORK_notify_transmit_ready_cancel (session->transmit_handle); |
@@ -804,6 +800,15 @@ disconnect_session (struct Session *session) | |||
804 | } | 800 | } |
805 | while (NULL != (pm = session->pending_messages)) | 801 | while (NULL != (pm = session->pending_messages)) |
806 | { | 802 | { |
803 | #if DEBUG_TCP | ||
804 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | ||
805 | "tcp", | ||
806 | pm->transmit_cont != NULL | ||
807 | ? "Could not deliver message of type %u to `%4s'.\n" | ||
808 | : "Could not deliver message of type %u to `%4s', notifying.\n", | ||
809 | ntohs(pm->msg->type), | ||
810 | GNUNET_i2s(&session->target)); | ||
811 | #endif | ||
807 | session->pending_messages = pm->next; | 812 | session->pending_messages = pm->next; |
808 | if (NULL != pm->transmit_cont) | 813 | if (NULL != pm->transmit_cont) |
809 | pm->transmit_cont (pm->transmit_cont_cls, | 814 | pm->transmit_cont (pm->transmit_cont_cls, |
@@ -811,12 +816,24 @@ disconnect_session (struct Session *session) | |||
811 | &session->target, GNUNET_SYSERR); | 816 | &session->target, GNUNET_SYSERR); |
812 | GNUNET_free (pm); | 817 | GNUNET_free (pm); |
813 | } | 818 | } |
814 | /* notify transport service about disconnect */ | 819 | if (GNUNET_NO == session->expecting_welcome) |
815 | session->plugin->env->receive (session->plugin->env->cls, | 820 | { |
816 | session, | 821 | #if DEBUG_TCP |
817 | session->service_context, | 822 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, |
818 | GNUNET_TIME_UNIT_ZERO, | 823 | "tcp", |
819 | &session->target, NULL); | 824 | "Notifying transport service about loss of data connection with `%4s'.\n", |
825 | GNUNET_i2s(&session->target)); | ||
826 | #endif | ||
827 | /* Data session that actually went past the | ||
828 | initial handshake; transport service may | ||
829 | know about this one, so we need to | ||
830 | notify transport service about disconnect */ | ||
831 | session->plugin->env->receive (session->plugin->env->cls, | ||
832 | session, | ||
833 | session->service_context, | ||
834 | GNUNET_TIME_UNIT_ZERO, | ||
835 | &session->target, NULL); | ||
836 | } | ||
820 | GNUNET_free_non_null (session->connect_addr); | 837 | GNUNET_free_non_null (session->connect_addr); |
821 | GNUNET_free (session); | 838 | GNUNET_free (session); |
822 | } | 839 | } |
@@ -1132,7 +1149,11 @@ tcp_plugin_send (void *cls, | |||
1132 | * @param plugin_context value we were asked to pass to this plugin | 1149 | * @param plugin_context value we were asked to pass to this plugin |
1133 | * to respond to the given peer (use is optional, | 1150 | * to respond to the given peer (use is optional, |
1134 | * but may speed up processing), can be NULL (if | 1151 | * but may speed up processing), can be NULL (if |
1135 | * NULL was returned from the transmit function) | 1152 | * NULL was returned from the transmit function); note |
1153 | * that use of NULL is dangerous since then this call may | ||
1154 | * cancel any session with the target peer (including | ||
1155 | * HELLO validation sessions), which is likely not what | ||
1156 | * is intended. | ||
1136 | * @param service_context must correspond to the service context | 1157 | * @param service_context must correspond to the service context |
1137 | * of the corresponding Transmit call; the plugin should | 1158 | * of the corresponding Transmit call; the plugin should |
1138 | * not cancel a send call made with a different service | 1159 | * not cancel a send call made with a different service |
@@ -1147,35 +1168,47 @@ tcp_plugin_cancel (void *cls, | |||
1147 | const struct GNUNET_PeerIdentity *target) | 1168 | const struct GNUNET_PeerIdentity *target) |
1148 | { | 1169 | { |
1149 | struct Plugin *plugin = cls; | 1170 | struct Plugin *plugin = cls; |
1171 | struct Session *session = plugin_context; | ||
1150 | struct PendingMessage *pm; | 1172 | struct PendingMessage *pm; |
1151 | struct Session *session; | ||
1152 | struct Session *next; | ||
1153 | 1173 | ||
1174 | if (session == NULL) | ||
1175 | { | ||
1176 | #if DEBUG_TCP | ||
1177 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, | ||
1178 | "tcp", | ||
1179 | "Asked to cancel with `%4s' without specification of specifics; will try to find an applicable session\n", | ||
1180 | GNUNET_i2s(target)); | ||
1181 | #endif | ||
1182 | session = find_session_by_target (plugin, target); | ||
1183 | } | ||
1184 | if (session == NULL) | ||
1185 | { | ||
1186 | GNUNET_break (0); | ||
1187 | return; | ||
1188 | } | ||
1189 | #if DEBUG_TCP | ||
1154 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | 1190 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, |
1155 | "tcp", | 1191 | "tcp", |
1156 | "Asked to close session with `%4s'\n", | 1192 | "Asked to cancel session %p with `%4s'\n", |
1193 | plugin_context, | ||
1157 | GNUNET_i2s(target)); | 1194 | GNUNET_i2s(target)); |
1158 | session = plugin->sessions; | 1195 | #endif |
1159 | while (session != NULL) | 1196 | pm = session->pending_messages; |
1197 | while (pm != NULL) | ||
1160 | { | 1198 | { |
1161 | next = session->next; | 1199 | pm->transmit_cont = NULL; |
1162 | if (0 == memcmp (target, | 1200 | pm->transmit_cont_cls = NULL; |
1163 | &session->target, sizeof (struct GNUNET_PeerIdentity))) | 1201 | pm = pm->next; |
1164 | { | 1202 | } |
1165 | pm = session->pending_messages; | 1203 | session->service_context = NULL; |
1166 | while (pm != NULL) | 1204 | if (session->client != NULL) |
1167 | { | 1205 | { |
1168 | pm->transmit_cont = NULL; | 1206 | GNUNET_SERVER_client_drop (session->client); |
1169 | pm->transmit_cont_cls = NULL; | 1207 | session->client = NULL; |
1170 | pm = pm->next; | ||
1171 | } | ||
1172 | session->service_context = NULL; | ||
1173 | GNUNET_SERVER_client_disconnect (session->client); | ||
1174 | /* rest of the clean-up of the session will be done as part of | ||
1175 | disconnect_notify which should be triggered any time now */ | ||
1176 | } | ||
1177 | session = next; | ||
1178 | } | 1208 | } |
1209 | /* rest of the clean-up of the session will be done as part of | ||
1210 | disconnect_notify which should be triggered any time now | ||
1211 | (or which may be triggering this call in the first place) */ | ||
1179 | } | 1212 | } |
1180 | 1213 | ||
1181 | 1214 | ||
diff --git a/src/transport/transport_api.c b/src/transport/transport_api.c index 239983983..d475de859 100644 --- a/src/transport/transport_api.c +++ b/src/transport/transport_api.c | |||
@@ -1054,6 +1054,11 @@ remove_neighbour (struct GNUNET_TRANSPORT_Handle *h, | |||
1054 | struct NeighbourList *pos; | 1054 | struct NeighbourList *pos; |
1055 | struct GNUNET_TRANSPORT_TransmitHandle *th; | 1055 | struct GNUNET_TRANSPORT_TransmitHandle *th; |
1056 | 1056 | ||
1057 | #if DEBUG_TRANSPORT | ||
1058 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1059 | "Removing neighbour `%s' from list of connected peers.\n", | ||
1060 | GNUNET_i2s (peer)); | ||
1061 | #endif | ||
1057 | prev = NULL; | 1062 | prev = NULL; |
1058 | pos = h->neighbours; | 1063 | pos = h->neighbours; |
1059 | while ((pos != NULL) && | 1064 | while ((pos != NULL) && |