+static int
+openssl_ctx_write_dtls (tls_ctx_t *ctx, session_t *app_session,
+ transport_send_params_t *sp)
+{
+ openssl_main_t *om = &openssl_main;
+ openssl_ctx_t *oc = (openssl_ctx_t *) ctx;
+ session_dgram_pre_hdr_t hdr;
+ session_t *us;
+ int wrote, rv;
+ u32 read = 0, to_deq, dgram_sz;
+ u8 *buf;
+
+ us = session_get_from_handle (ctx->tls_session_handle);
+ to_deq = svm_fifo_max_dequeue_cons (app_session->tx_fifo);
+ buf = om->tx_bufs[ctx->c_thread_index];
+
+ while (to_deq > 0)
+ {
+ /* Peeking only pre-header dgram because the session is connected */
+ rv = svm_fifo_peek (app_session->tx_fifo, 0, sizeof (hdr), (u8 *) &hdr);
+ ASSERT (rv == sizeof (hdr) && hdr.data_length < vec_len (buf));
+ ASSERT (to_deq >= hdr.data_length + SESSION_CONN_HDR_LEN);
+
+ dgram_sz = hdr.data_length + SESSION_CONN_HDR_LEN;
+ if (svm_fifo_max_enqueue_prod (us->tx_fifo) < dgram_sz + TLSO_CTRL_BYTES)
+ {
+ svm_fifo_add_want_deq_ntf (us->tx_fifo, SVM_FIFO_WANT_DEQ_NOTIF);
+ transport_connection_deschedule (&ctx->connection);
+ sp->flags |= TRANSPORT_SND_F_DESCHED;
+ goto done;
+ }
+
+ rv = svm_fifo_peek (app_session->tx_fifo, SESSION_CONN_HDR_LEN,
+ hdr.data_length, buf);
+ ASSERT (rv == hdr.data_length);
+ svm_fifo_dequeue_drop (app_session->tx_fifo, dgram_sz);
+
+ wrote = SSL_write (oc->ssl, buf, rv);
+ ASSERT (wrote > 0);
+
+ read += rv;
+ to_deq -= dgram_sz;
+ }
+
+done:
+
+ if (svm_fifo_needs_deq_ntf (app_session->tx_fifo, read))
+ session_dequeue_notify (app_session);
+
+ if (read)
+ tls_add_vpp_q_tx_evt (us);
+
+ if (PREDICT_FALSE (ctx->app_closed &&
+ !svm_fifo_max_enqueue_prod (us->rx_fifo)))
+ openssl_confirm_app_close (ctx);
+
+ return read;
+}
+
+static inline int
+openssl_ctx_write (tls_ctx_t *ctx, session_t *app_session,
+ transport_send_params_t *sp)
+{
+ if (ctx->tls_type == TRANSPORT_PROTO_TLS)
+ return openssl_ctx_write_tls (ctx, app_session, sp);
+ else
+ return openssl_ctx_write_dtls (ctx, app_session, sp);
+}
+