*/
struct GNUNET_MESH_TransmitHandle *transmit_handle;
+ /**
+ * The current act transmit handle (if a pending ack transmit request exists)
+ */
+ struct GNUNET_MESH_TransmitHandle *ack_transmit_handle;
+
+ /**
+ * Pointer to the current ack message using in ack_task
+ */
+ struct GNUNET_STREAM_AckMessage *ack_msg;
+
/**
* The current message associated with the transmit handle
*/
static size_t
send_ack_notify (void *cls, size_t size, void *buf)
{
- struct GNUNET_STREAM_AckMessage *ack_msg = cls;
+ struct GNUNET_STREAM_Socket *socket = cls;
if (0 == size)
{
"%s called with size 0\n", __func__);
return 0;
}
- GNUNET_assert (ntohs (ack_msg->header.header.size) <= size);
+ GNUNET_assert (ntohs (socket->ack_msg->header.header.size) <= size);
+
+ size = ntohs (socket->ack_msg->header.header.size);
+ memcpy (buf, socket->ack_msg, size);
- size = ntohs (ack_msg->header.header.size);
- memcpy (buf, ack_msg, size);
+ GNUNET_free (socket->ack_msg);
+ socket->ack_msg = NULL;
+ socket->ack_transmit_handle = NULL;
return size;
}
ack_msg->receive_window_remaining =
htonl (RECEIVE_BUFFER_SIZE - socket->receive_buffer_size);
+ socket->ack_msg = ack_msg;
GNUNET_PEER_resolve (socket->other_peer, &target);
/* Request MESH for sending ACK */
- GNUNET_MESH_notify_transmit_ready (socket->tunnel,
- 0, /* Corking */
- 1, /* Priority */
- socket->retransmit_timeout,
- &target,
- ntohs (ack_msg->header.header.size),
- &send_ack_notify,
- ack_msg);
-
-
+ socket->ack_transmit_handle =
+ GNUNET_MESH_notify_transmit_ready (socket->tunnel,
+ 0, /* Corking */
+ 1, /* Priority */
+ socket->retransmit_timeout,
+ &target,
+ ntohs (ack_msg->header.header.size),
+ &send_ack_notify,
+ socket);
}
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "%x: Received TRAMSMIT_CLOSE_ACK from %x\n",
+ "%x: Received TRANSMIT_CLOSE_ACK from %x\n",
socket->our_id,
socket->other_peer);
socket->state = STATE_TRANSMIT_CLOSED;
void *tunnel_ctx)
{
struct GNUNET_STREAM_Socket *socket = tunnel_ctx;
-
+
+ if (tunnel != socket->tunnel)
+ return;
+
+ GNUNET_break_op(0);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"%x: Peer %x has terminated connection abruptly\n",
socket->our_id,
GNUNET_MESH_notify_transmit_ready_cancel (socket->transmit_handle);
socket->transmit_handle = NULL;
}
+ if (NULL != socket->ack_transmit_handle)
+ {
+ GNUNET_MESH_notify_transmit_ready_cancel (socket->ack_transmit_handle);
+ GNUNET_free (socket->ack_msg);
+ socket->ack_msg = NULL;
+ socket->ack_transmit_handle = NULL;
+ }
+ /* Stop Tasks using socket->tunnel */
+ if (GNUNET_SCHEDULER_NO_TASK != socket->ack_task_id)
+ {
+ GNUNET_SCHEDULER_cancel (socket->ack_task_id);
+ socket->ack_task_id = GNUNET_SCHEDULER_NO_TASK;
+ }
+ if (GNUNET_SCHEDULER_NO_TASK != socket->retransmission_timeout_task_id)
+ {
+ GNUNET_SCHEDULER_cancel (socket->retransmission_timeout_task_id);
+ socket->retransmission_timeout_task_id = GNUNET_SCHEDULER_NO_TASK;
+ }
+ /* FIXME: Cancel all other tasks using socket->tunnel */
socket->tunnel = NULL;
}
10, /* QUEUE size as parameter? */
socket, /* cls */
NULL, /* No inbound tunnel handler */
- &tunnel_cleaner, /* FIXME: not required? */
+ NULL, /* No in-tunnel cleaner */
client_message_handlers,
ports); /* We don't get inbound tunnels */
if (NULL == socket->mesh) /* Fail if we cannot connect to mesh */
GNUNET_MESH_notify_transmit_ready_cancel (socket->transmit_handle);
socket->transmit_handle = NULL;
}
+ if (NULL != socket->ack_transmit_handle)
+ {
+ GNUNET_MESH_notify_transmit_ready_cancel (socket->ack_transmit_handle);
+ GNUNET_free (socket->ack_msg);
+ socket->ack_msg = NULL;
+ socket->ack_transmit_handle = NULL;
+ }
/* Clear existing message queue */
while (NULL != (head = socket->queue_head)) {