aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/transport/gnunet-service-transport.c27
-rw-r--r--src/transport/plugin_transport.h6
-rw-r--r--src/transport/plugin_transport_tcp.c119
-rw-r--r--src/transport/transport_api.c5
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) &&