/* * Send a packet to TCP/UDP socket. */ static inline void multi_process_outgoing_link (struct multi_context *m, const unsigned int mpp_flags) { struct multi_instance *mi = multi_process_outgoing_link_pre (m); if (mi) multi_process_outgoing_link_dowork (m, mi, mpp_flags); }
static bool multi_tcp_process_outgoing_link(struct multi_context *m, bool defer, const unsigned int mpp_flags) { struct multi_instance *mi = multi_process_outgoing_link_pre(m); bool ret = true; if (mi) { if (defer || mbuf_defined(mi->tcp_link_out_deferred)) { /* save to queue */ struct buffer *buf = &mi->context.c2.to_link; if (BLEN(buf) > 0) { struct mbuf_buffer *mb = mbuf_alloc_buf(buf); struct mbuf_item item; set_prefix(mi); dmsg(D_MULTI_TCP, "MULTI TCP: queuing deferred packet"); item.buffer = mb; item.instance = mi; mbuf_add_item(mi->tcp_link_out_deferred, &item); mbuf_free_buf(mb); buf_reset(buf); ret = multi_process_post(m, mi, mpp_flags); if (!ret) { mi = NULL; } clear_prefix(); } } else { ret = multi_process_outgoing_link_dowork(m, mi, mpp_flags); if (!ret) { mi = NULL; } } } return ret; }
static bool multi_tcp_process_outgoing_link_ready(struct multi_context *m, struct multi_instance *mi, const unsigned int mpp_flags) { struct mbuf_item item; bool ret = true; ASSERT(mi); /* extract from queue */ if (mbuf_extract_item(mi->tcp_link_out_deferred, &item)) /* ciphertext IP packet */ { dmsg(D_MULTI_TCP, "MULTI TCP: transmitting previously deferred packet"); ASSERT(mi == item.instance); mi->context.c2.to_link = item.buffer->buf; ret = multi_process_outgoing_link_dowork(m, mi, mpp_flags); if (!ret) { mi = NULL; } mbuf_free_buf(item.buffer); } return ret; }