blob: c97b333840bb7f5d896999fbedec6246d07dda46 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
module network.mojom;
import "mojo/public/mojom/base/read_only_buffer.mojom";
import "services/network/public/mojom/ip_address.mojom";
import "services/network/public/mojom/ip_endpoint.mojom";
import "services/network/public/mojom/mutable_network_traffic_annotation_tag.mojom";
// Represents options that consumers can set when requesting a UDPSocket
// interface pointer.
struct UDPSocketOptions {
// If true, this enables SO_REUSEADDR on the underlying socket.
bool allow_address_reuse = false;
// If true, allows sending and receiving packets to and from broadcast
// addresses. It's recommended this be used instead of SetBroadcast(), as
// Bind() may fail on some platforms when reusing a UDP port and broadcast
// is not enabled when the socket is created.
bool allow_broadcast = false;
// If true, allows the socket to share the local address to which the socket
// will be bound with other processes and attempts to allow all such sockets
// to receive the same multicast messages.
//
// For best cross-platform results in allowing the messages to be shared, all
// sockets sharing the same address should join the same multicast group (via
// UDPSocket::JoinGroup()) and set the same |multicast_interface|. Also, the
// socket should bind to the specific multicast group address rather than a
// wildcard address (e.g. 0.0.0.0) on platforms where doing so is allowed.
bool allow_address_sharing_for_multicast = false;
// Sets interface to use for multicast. Default value is 0, in which case the
// default interface is used.
uint32 multicast_interface = 0;
// Sets the time-to-live option for UDP packets sent to the multicast
// group address. The default value of this option is 1. Cannot be more than
// 255.
uint32 multicast_time_to_live = 1;
// Sets the loopback flag for UDP socket. If this flag is true and the socket
// joins a group through JoinGroup(), the socket will receive packets sent to
// the joined group from itself. The default value of this option is true.
//
// Note: the behavior of |SetMulticastLoopbackMode| is slightly
// different between Windows and Unix-like systems. The inconsistency only
// happens when there are more than one applications on the same host
// joined to the same multicast group while having different settings on
// multicast loopback mode. On Windows, the applications with loopback off
// will not RECEIVE the loopback packets; while on Unix-like systems, the
// applications with loopback off will not SEND the loopback packets to
// other applications on the same host. See MSDN: http://goo.gl/6vqbj
bool multicast_loopback_mode = true;
// Sets the OS send buffer size (in bytes) for the socket. This is the
// SO_SNDBUF socket option. This socket option matters less for UDP socket (as
// compared to TCP), because in theory all UDP data written to the kernel
// should directly go out to the network. The kernel usually doesn't need to
// buffer send data. Default value is 0, in which case, OS's default value
// will be used.
int32 send_buffer_size = 0;
// Sets the OS receive buffer size (in bytes) for the socket. This is the
// SO_RCVBUF socket option. The kernel allocates this much to hold the data
// arriving into this socket between the time when data arrives over the
// network and when it is read by UDPSocketReceiver. If buffer is full,
// new packets will be discarded. Default value is 0, in which case, OS's
// default value will be used.
int32 receive_buffer_size = 0;
};
// UDPSocket is an interface that exposes UDP socket functionalities.
// UDPSocketReceiver is an interface that allows consumers to consume data
// received by the UDPSocket. The typical flow of using the interfaces is:
// - Acquire a UDPSocket interface pointer and optionally supply a non-null
// UDPSocketReceiverPtr. If consumers are not interested in received data, a
// null UDPSocketReceiverPtr is acceptable.
// - Use either Bind() or Connect() before datagrams can be sent or received.
// - (optional) Invoke setters (e.g. SetBroadcast()).
// - Send / request to receive datagrams. Received datagrams will be delivered
// to the bound receiver's OnReceived() call.
// - Close the socket by destroying the interface pointer.
interface UDPSocket {
// Binds the address/port for this socket to |local_addr|. Caller can use port
// 0 to let the OS pick an available port. If |socket_options| is not null,
// configures the socket with the options before binding the socket.
// Returns net::OK and the real local address used on success and a negative
// net error code on failure.
Bind(IPEndPoint local_addr, UDPSocketOptions? socket_options)
=> (int32 result, IPEndPoint? local_addr_out);
// Connects the socket to |remote_addr|. This automatically binds the socket
// to an available local port, so this cannot be used with Bind().
// If |socket_options| is not null, configures the socket with the options
// before connecting the socket.
// The address family of the local socket will be of the same
// AddressFamily as |remote_addr|. Returns net::OK and the local address of
// socket on success. Subsequent packets received will be from |remote_addr|.
// Returns a negative net error code on failure.
Connect(IPEndPoint remote_addr, UDPSocketOptions? socket_options) =>
(int32 result, IPEndPoint? local_addr_out);
// Allows or disallows sending and receiving packets to and from broadcast
// addresses. Returns a net error code. Should only be called after Bind().
SetBroadcast(bool broadcast) => (int32 result);
// Sets the OS send buffer size (in bytes) for the socket. Overwrites any
// previously set value. Returns a net error code.
// See |UDPSocketOptions::send_buffer_size| for more information.
SetSendBufferSize(int32 send_buffer_size) => (int32 result);
// Sets the OS receive buffer size (in bytes) for the socket. Overwrites any
// previously set value. Returns a net error code.
// See |UDPSocketOptions::receive_buffer_size| for more information.
SetReceiveBufferSize(int32 receive_buffer_size) => (int32 result);
// Joins a multicast group. |group_address| is the group address to join,
// could be either an IPv4 or IPv6 address. Returns a net error code.
// See RFC 1112 for details on multicast.
JoinGroup(IPAddress group_address) => (int32 result);
// Leaves the multicast group. |group_address| is the group address to leave,
// could be either an IPv4 or IPv6 address. If the socket hasn't joined the
// group, this call will be ignored. It's optional to leave the multicast
// group before destroying the socket. Returns a net error code.
LeaveGroup(IPAddress group_address) => (int32 result);
// Notifies that the receiver is ready to accept |number| of datagrams.
// Correspondingly, OnReceived() of the UDPSocketReceiver interface will be
// called |number| times (errors also count), unless the connection is closed
// before that. The implementation may return net::ERR_INSUFFICIENT_RESOURCES
// in an OnReceived() callback if the service doesn't have enough resource to
// complete the operation. For example, if the implementation queues the
// requests internally, net::ERR_INSUFFICIENT_RESOURCES can be returned if the
// queue doesn't have any space to accept new ReceiveMore().
//
// It is allowed to call this method again before the previous request is
// completely satisfied. For example:
// service->ReceiveMore(3);
// ...
// // OnReceived() is called.
// // OnReceived() is called.
// ...
// service->ReceiveMore(3);
// // The client expects 4 more calls to OnReceived().
//
// Please note that how ReceiveMore() is used will affect performance
// significantly. For example:
// // Approach 1:
// service->ReceiveMore(3);
// // OnReceived() is called.
// // OnReceived() is called.
// // OnReceived() is called.
//
// // Approach 2:
// service->ReceiveMore(1);
// // OnReceived() is called.
// service->ReceiveMore(1);
// // OnReceived() is called.
// service->ReceiveMore(1);
// // OnReceived() is called.
//
// It is very likely that approach 1 will perform better than approach 2,
// because in approach 2 getting every datagram takes at least the time of a
// round trip to the service side. Default buffer size of 64KiB will be
// allocated to receive each datagram.
ReceiveMore(uint32 num_additional_datagrams);
// Same as ReceiveMore(), but with an ability to set the buffer size used for
// receiving each datagram. Note that |buffer_size| is the application-side
// buffer which is different from UDPSocketOptions::receive_buffer_size which
// is the OS-side buffer. |buffer_size| larger than 64KiB will be capped at
// 64KiB as the limit on data length of a IPv4 UDP packet is 65,507 and 65,535
// for IPv6.
ReceiveMoreWithBufferSize(
uint32 num_additional_datagrams, uint32 buffer_size);
// Sends data to a particular destination, |dest_addr|. Should only be used
// after Bind(). There is currently no limit on the size of |data|, other
// than the restrictions on datagram size specified in the IP layer (e.g.
// 65507 bytes for IPv4) . Consumers need to be aware that sending data in
// larger chunks will result in higher memory usage. Upon successfully handing
// the data to the OS, |result| is net::OK. On failure, it is a network error
// code, including (but not limited to):
// - net::ERR_INSUFFICIENT_RESOURCES: The service doesn't have
// sufficient resource to complete the operation. When this happens, the
// requests will be failed quickly (which might happen before the completion
// of requests that were sent earlier).
SendTo(IPEndPoint dest_addr,
mojo_base.mojom.ReadOnlyBuffer data,
MutableNetworkTrafficAnnotationTag traffic_annotation)
=> (int32 result);
// Same as SendTo(), except this method sends data to the destination
// specified in an earlier Connect(). This method should only be called after
// a successful Connect().
Send(mojo_base.mojom.ReadOnlyBuffer data,
MutableNetworkTrafficAnnotationTag traffic_annotation)
=> (int32 result);
// Closes the socket. Connect() or Bind() can be used after Close().
Close();
};
// An interface the consumers of UDPSocket can implement to listen for incoming
// packets. This interface is to be used together when requesting a UDPSocket.
interface UDPSocketReceiver {
// Invoked when data is received.
// - When UDPSocket is used with Bind():
// On success, |result| is net::OK. |src_addr| indicates the address of the
// sender. |data| contains the received data.
// On failure, |result| is a negative network error code. |data| is null.
// |src_addr| might be null.
// - When UDPSocket is used with Connect():
// |src_addr| is always null. Data are always received from the remote
// address specified in Connect().
// On success, |result| is net::OK. |data| contains the received data.
// On failure, |result| is a negative network error code. |data| is null.
//
// Note that in both cases, |data| can be an empty buffer when |result| is
// net::OK, which indicates a zero-byte payload.
OnReceived(int32 result,
IPEndPoint? src_addr,
mojo_base.mojom.ReadOnlyBuffer? data);
};