*/
void *pcic_cls;
+ /**
+ * Pointer to free when we call pcic.
+ */
+ void *pcic_ptr;
+
/**
* Request information ID for the given pcic (needed in case a
* request is cancelled after being submitted to core and a new
*/
uint16_t smr_id;
+ /**
+ * Is corking allowed?
+ */
+ int cork;
+
};
if (NULL != (pcic = pr->pcic))
{
pr->pcic = NULL;
+ GNUNET_free_non_null (pr->pcic_ptr);
+ pr->pcic_ptr = NULL;
pcic (pr->pcic_cls,
&pr->peer,
zero,
- 0, 0);
+ 0,
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ 0);
}
if (pr->timeout_task != GNUNET_SCHEDULER_NO_TASK)
{
sm->priority = htonl (th->priority);
sm->deadline = GNUNET_TIME_absolute_hton (th->timeout);
sm->peer = pr->peer;
+ sm->cork = htonl ((uint32_t) th->cork);
+ sm->reserved = htonl (0);
ret = th->get_message (th->get_message_cls,
size - sizeof (struct SendMessage),
&sm[1]);
#endif
/* client decided to send nothing! */
request_next_transmission (pr);
- return 0;
+ GNUNET_free (th);
+ return 0;
}
#if DEBUG_CORE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
{
GNUNET_break (0);
request_next_transmission (pr);
- return 0;
+ GNUNET_free (th);
+ return 0;
}
ret += sizeof (struct SendMessage);
sm->header.size = htons (ret);
&cnm->peer,
sizeof (struct GNUNET_PeerIdentity)))
{
- /* disconnect from self!? */
+ /* connect to self!? */
GNUNET_break (0);
return;
}
if (NULL == h->status_events)
{
GNUNET_break (0);
+ return;
}
if (msize < sizeof (struct PeerStatusNotifyMessage))
{
}
pcic = pr->pcic;
pr->pcic = NULL;
+ GNUNET_free_non_null (pr->pcic_ptr);
+ pr->pcic_ptr = NULL;
if (pcic != NULL)
pcic (pr->pcic_cls,
&pr->peer,
cim->bw_out,
ntohl (cim->reserved_amount),
+ GNUNET_TIME_relative_ntoh (cim->reserve_delay),
GNUNET_ntohll (cim->preference));
break;
default:
/**
* Ask the core to call "notify" once it is ready to transmit the
- * given number of bytes to the specified "target". If we are not yet
- * connected to the specified peer, a call to this function will cause
- * us to try to establish a connection.
+ * given number of bytes to the specified "target". Must only be
+ * called after a connection to the respective peer has been
+ * established (and the client has been informed about this).
*
* @param handle connection to core service
+ * @param cork is corking allowed for this transmission?
* @param priority how important is the message?
* @param maxdelay how long can the message wait?
* @param target who should receive the message,
*/
struct GNUNET_CORE_TransmitHandle *
GNUNET_CORE_notify_transmit_ready (struct GNUNET_CORE_Handle *handle,
+ int cork,
uint32_t priority,
struct GNUNET_TIME_Relative maxdelay,
const struct GNUNET_PeerIdentity *target,
th->timeout = GNUNET_TIME_relative_to_absolute (maxdelay);
th->priority = priority;
th->msize = notify_size;
+ th->cork = cork;
/* bound queue size */
if (pr->queue_size == handle->queue_size)
{
if (minp == NULL)
{
GNUNET_break (handle->queue_size != 0);
- GNUNET_break (pr->queue_size == 0);
+ GNUNET_break (pr->queue_size == 1);
GNUNET_free(th);
+#if DEBUG_CORE
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Dropping transmission request: cannot drop queue head and limit is one\n");
+#endif
return NULL;
}
if (priority <= minp->priority)
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Dropping transmission request: priority too low\n");
#endif
+ GNUNET_free(th);
return NULL; /* priority too low */
}
GNUNET_CONTAINER_DLL_remove (pr->pending_head,
* @param peer who should we connect to
* @param cont function to call once the request has been completed (or timed out)
* @param cont_cls closure for cont
- * @return NULL on error (cont will not be called), otherwise handle for cancellation
+ *
+ * @return NULL on error or already connected,
+ * otherwise handle for cancellation
*/
struct GNUNET_CORE_PeerRequestHandle *
GNUNET_CORE_peer_request_connect (struct GNUNET_CORE_Handle *h,
struct GNUNET_CORE_PeerRequestHandle *ret;
struct ControlMessage *cm;
struct ConnectMessage *msg;
+
+ if (NULL != GNUNET_CONTAINER_multihashmap_get (h->peers,
+ &peer->hashPubKey))
+ {
+#if DEBUG_CORE
+ GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
+ "Peers are already connected!\n");
+#endif
+ return NULL;
+ }
cm = GNUNET_malloc (sizeof (struct ControlMessage) +
sizeof (struct ConnectMessage));
msg->reserved = htonl (0);
msg->timeout = GNUNET_TIME_relative_hton (timeout);
msg->peer = *peer;
- GNUNET_CONTAINER_DLL_insert (h->control_pending_head,
- h->control_pending_tail,
- cm);
+ GNUNET_CONTAINER_DLL_insert_tail (h->control_pending_head,
+ h->control_pending_tail,
+ cm);
ret = GNUNET_malloc (sizeof (struct GNUNET_CORE_PeerRequestHandle));
ret->h = h;
ret->cm = cm;
*/
struct GNUNET_CORE_Handle *h;
- /**
- * Function to call with the information.
- */
- GNUNET_CORE_PeerConfigurationInfoCallback info;
-
- /**
- * Closure for info.
- */
- void *info_cls;
-
/**
* Link to control message, NULL if CM was sent.
*/
irc = GNUNET_malloc (sizeof (struct GNUNET_CORE_InformationRequestContext));
irc->h = h;
irc->pr = pr;
- irc->info = info;
- irc->info_cls = info_cls;
cm = GNUNET_malloc (sizeof (struct ControlMessage) +
sizeof (struct RequestInfoMessage));
cm->cont = &change_preference_send_continuation;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Queueing CHANGE PREFERENCE request\n");
#endif
- GNUNET_CONTAINER_DLL_insert (h->control_pending_head,
- h->control_pending_tail,
- cm);
+ GNUNET_CONTAINER_DLL_insert_tail (h->control_pending_head,
+ h->control_pending_tail,
+ cm);
pr->pcic = info;
pr->pcic_cls = info_cls;
+ pr->pcic_ptr = irc; /* for free'ing irc */
if (h->control_pending_head == cm)
trigger_next_request (h, GNUNET_NO);
return irc;
struct GNUNET_CORE_Handle *h = irc->h;
struct PeerRecord *pr = irc->pr;
+ GNUNET_assert (pr->pcic_ptr == irc);
if (irc->cm != NULL)
{
GNUNET_CONTAINER_DLL_remove (h->control_pending_head,
}
pr->pcic = NULL;
pr->pcic_cls = NULL;
+ pr->pcic_ptr = NULL;
GNUNET_free (irc);
}