ngtcp2_conn_writev_datagram

Synopsis

#include <ngtcp2/ngtcp2.h>

ngtcp2_ssize ngtcp2_conn_writev_datagram(ngtcp2_conn *conn, ngtcp2_path *path, ngtcp2_pkt_info *pi, uint8_t *dest, size_t destlen, int *paccepted, uint32_t flags, uint64_t dgram_id, const ngtcp2_vec *datav, size_t datavcnt, ngtcp2_tstamp ts)

ngtcp2_conn_writev_datagram() writes a packet containing unreliable data in DATAGRAM frame. The buffer of the packet is pointed by dest of length destlen. This function performs QUIC handshake as well.

destlen should be at least ngtcp2_settings.max_tx_udp_payload_size. It must be at least NGTCP2_MAX_UDP_PAYLOAD_SIZE.

For path and pi parameters, refer to ngtcp2_conn_writev_stream().

Stream data is specified as vector of data datav. datavcnt specifies the number of ngtcp2_vec that datav includes.

If the given data is written to the buffer, nonzero value is assigned to *paccepted if it is not NULL. The data in DATAGRAM frame cannot be fragmented; writing partial data is not possible.

dgram_id is an opaque identifier which should uniquely identify the given DATAGRAM data. It is passed to ngtcp2_callbacks.ack_datagram callback when a packet that contains DATAGRAM frame is acknowledged. It is also passed to ngtcp2_callbacks.lost_datagram callback when a packet that contains DATAGRAM frame is declared lost. If an application uses neither of those callbacks, it can sets 0 to this parameter.

This function might write other frames other than DATAGRAM frame, just like ngtcp2_conn_writev_stream().

If the function returns 0, it means that no more data cannot be sent because of congestion control limit; or, data does not fit into the provided buffer; or, a local endpoint, as a server, is unable to send data because of its amplification limit. In this case, *paccepted is assigned zero if it is not NULL.

If NGTCP2_WRITE_DATAGRAM_FLAG_MORE is set in flags, there are 3 outcomes:

  • The function returns the written length of packet just like without NGTCP2_WRITE_DATAGRAM_FLAG_MORE. This is because packet is nearly full and the library decided to make a complete packet. *paccepted might be zero or nonzero.

  • The function returns NGTCP2_ERR_WRITE_MORE. In this case, *paccepted != 0 is asserted. This indicates that application can call this function with another unreliable data (or ngtcp2_conn_writev_stream() if it has stream data to send) to pack them into the same packet. Application has to specify the same conn, path, pi, dest, destlen, and ts parameters, otherwise the behaviour is undefined. The application can change flags.

  • The other error might be returned just like without NGTCP2_WRITE_DATAGRAM_FLAG_MORE.

When application sees NGTCP2_ERR_WRITE_MORE, it must not call other ngtcp2 API functions (application can still call ngtcp2_conn_write_connection_close() to handle error from this function. It can also call ngtcp2_conn_shutdown_stream_read(), ngtcp2_conn_shutdown_stream_write(), and ngtcp2_conn_shutdown_stream()). Just keep calling this function (or ngtcp2_conn_writev_stream()) until it returns a positive number (which indicates a complete packet is ready).

This function returns the number of bytes written in dest if it succeeds, or one of the following negative error codes:

NGTCP2_ERR_NOMEM

Out of memory

NGTCP2_ERR_PKT_NUM_EXHAUSTED

Packet number is exhausted, and cannot send any more packet.

NGTCP2_ERR_CALLBACK_FAILURE

User callback failed

NGTCP2_ERR_WRITE_MORE

(Only when NGTCP2_WRITE_DATAGRAM_FLAG_MORE is specified) Application can call this function to pack more data into the same packet. See above to know how it works.

NGTCP2_ERR_INVALID_STATE

A remote endpoint did not express the DATAGRAM frame support.

NGTCP2_ERR_INVALID_ARGUMENT

The provisional DATAGRAM frame size exceeds the maximum DATAGRAM frame size that a remote endpoint can receive.

If any other negative error is returned, call ngtcp2_conn_write_connection_close() to get terminal packet, and sending it makes QUIC connection enter the closing state.