aboutsummaryrefslogtreecommitdiff
path: root/src/transport/plugin_transport_tcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/plugin_transport_tcp.c')
-rw-r--r--src/transport/plugin_transport_tcp.c119
1 files changed, 76 insertions, 43 deletions
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