diff options
Diffstat (limited to 'src/transport/plugin_transport_tcp.c')
-rw-r--r-- | src/transport/plugin_transport_tcp.c | 119 |
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 | ||