Module Luv.UDP

UDP sockets.

See UDP in the user guide and uv_udp_t — UDP handle in libuv.

type t = [ `UDP ] Handle.t

Binds uv_udp_t.

Note that values of this type can be passed to functions in Luv.Handle, in addition to the functions in this module. In particular, see Luv.Handle.close.

val init : ?⁠loop:Loop.t -> ?⁠domain:Sockaddr.Address_family.t -> ?⁠recvmmsg:bool -> unit -> (tError.t) Result.result

Allocates and initializes a UDP socket.

Binds uv_udp_init_ex.

On libuv prior to 1.7.0, using ?domain causes this function to return Error `ENOSYS ("Function not implemented").

?recvmmsg is requires Luv 0.5.2 and libuv 1.37.0. Passing it with earlier libuv has no effect.

Feature checks:

  • Luv.Require.(has udp_init_ex)
  • Luv.Require.(has udp_recvmmg)
val open_ : t -> Os_fd.Socket.t -> (unit, Error.t) Result.result

Wraps an existing socket in a libuv UDP handle.

Binds uv_udp_open.

val bind : ?⁠ipv6only:bool -> ?⁠reuseaddr:bool -> t -> Sockaddr.t -> (unit, Error.t) Result.result

Assigns an address to the given UDP handle.

Binds uv_udp_bind. See bind(3p).

val getsockname : t -> (Sockaddr.tError.t) Result.result

Retrieves the address assigned to the given UDP handle.

Binds uv_udp_getsockname. See getsockname(3p).

module Membership : sig ... end

Binds uv_membership.

val set_membership : t -> group:string -> interface:string -> Membership.t -> (unit, Error.t) Result.result

Sets multicast group membership.

Binds uv_udp_set_membership.

val set_source_membership : t -> group:string -> interface:string -> source:string -> Membership.t -> (unit, Error.t) Result.result

Sets source-specific multicast group membership.

Binds uv_udp_set_source_membership.

Requires libuv 1.32.0.

Feature check: Luv.Require.(has udp_set_source_membership)

val set_multicast_loop : t -> bool -> (unit, Error.t) Result.result

Sets multicast loopback.

Binds uv_udp_set_multicast_loop.

val set_multicast_ttl : t -> int -> (unit, Error.t) Result.result

Sets the multicast TTL.

Binds uv_udp_set_multicast_ttl.

val set_multicast_interface : t -> string -> (unit, Error.t) Result.result

Sets the interface to be used for multicast.

Binds uv_udp_set_multicast_interface.

val set_broadcast : t -> bool -> (unit, Error.t) Result.result

Sets broadcast.

Binds uv_udp_set_broadcast.

val set_ttl : t -> int -> (unit, Error.t) Result.result

Sets the TTL.

Binds uv_udp_set_ttl.

val send : t -> Buffer.t list -> Sockaddr.t -> ((unit, Error.t) Result.result -> unit) -> unit

Sends a datagram.

Binds uv_udp_send. See send(3p).

For connected UDP sockets, see Luv.UDP.Connected.send.

val try_send : t -> Buffer.t list -> Sockaddr.t -> (unit, Error.t) Result.result

Like Luv.UDP.send, but only attempts to send the datagram immediately.

Binds uv_udp_try_send.

For connected UDP sockets, see Luv.UDP.Connected.try_send.

module Recv_flag : sig ... end

Binds uv_udp_flags.

val recv_start : ?⁠allocate:(int -> Buffer.t) -> t -> ((Buffer.t * Sockaddr.t option * Recv_flag.t listError.t) Result.result -> unit) -> unit

Calls its callback whenever a datagram is received on the UDP socket.

Binds uv_udp_recv_start. See uv_udp_recv_cb and recv(3p).

The behavior is similar to Luv.Stream.read_start. See that function for the meaning of the ?allocate callback.

The main callback takes a Sockaddr.t option. This is usually Some sender_address, carrying the address of the peer. None usually indicates EAGAIN in libuv; libuv still calls the callback, in order to give the C user a chance to deallocate the data buffer. Since this is not usually an issue in OCaml, it is usually safe to simply ignore calls to the callback with sender address None.

The buffer can be empty (Luv.Buffer.size buffer = 0). This indicates an empty datagram.

Since UDP is connectionless, there is no EOF, and no means to indicate it.

The Recv_flag.t list callback argument can contain `PARTIAL, which indicates that the buffer allocated was too small for the datagram, a prefix of the data was received, and the rest of the datagram was dropped.

In summary, the important possible combinations of callback arguments are:

  • Error _: “true” error that should be handled, reported, etc.
  • Ok (_, None, _): EAGAIN inside libuv. Should typically be ignored.
  • Ok (buffer, Some peer, flags): datagram received. In this case, there are additional possibilities:

    • Luv.Buffer.size buffer = 0: the datagram is empty, because an empty datagram was sent.
    • List.mem `PARTIAL flags = true: the read was partial, because the buffer was too small for the datagram.
val recv_stop : t -> (unit, Error.t) Result.result

Stops the callback provided to Luv.UDP.recv_start.

Binds uv_udp_recv_stop.

val using_recvmmsg : t -> bool

Evaluates to true if and only if the given handle was created with ~recvmmsg:true and the platform supports recvmmsg(2).

Binds uv_udp_using_recvmmsg.

Requires Luv 0.5.5 and libuv 1.39.0.

Feature check: Luv.Require.(has udp_using_recvmmsg)

val get_send_queue_size : t -> int

Binds uv_udp_get_send_queue_size.

val get_send_queue_count : t -> int

Binds uv_udp_get_send_queue_count.

module Connected : sig ... end

Connected UDP sockets.