aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-node/src/meshbay_node/transport/webrtc/udp_buffer.py
blob: 8a2db3163599eea016fc02720296b739cd2431aa (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
"""A larger receive buffer on the node's ICE sockets, applied on import.

aioice asks the kernel for 256 KB per socket. The node reads its sockets from
Python, more slowly than a line delivers, and a browser sending a file keeps up
to 1.5 MB in flight (32 chunks of 48 KB, `transport-upload.js`). What does not
fit in the buffer is dropped by the kernel of the node's own machine
(`UdpRcvbufErrors`), the browser's SCTP sender takes each drop for congestion,
and an upload settles around 6.5 MB/s on a line that carries 47
(docs/MESHBAY_DESIGN.md §5.5).

The buffer has to hold what one upload may have in flight, counted the way the
kernel counts it, which is about twice the bytes for packets of this size. The
kernel grants no more than `net.core.rmem_max` allows, and on a machine where
that is left at its default of 208 KB this changes nothing: `granted()` says
what a socket really gets, and the node logs it once.
"""

import socket

import aioice.turn

WANTED = 4 * 1024 * 1024

aioice.turn.UDP_SOCKET_BUFFER_SIZE = WANTED


def granted() -> int:
    """What the kernel gives a socket that asks for `WANTED`, in bytes."""
    with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
        try:
            sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, WANTED)
        except OSError:
            pass
        return sock.getsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF)