Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2c10321e authored by Maciej Żenczykowski's avatar Maciej Żenczykowski
Browse files

Dns over TLS - lower mss for ipv4 by 8



Clat/464xlat has to assume that it may need to translate
ipv4 fragments to ipv6.  As such the clat overhead is 28
(40 ipv6 header size - 20 ipv4 header size + 8 ipv6 frag header)
and not 20.

This means on a minimum ipv6 mtu 1280 ipv6-only network,
the clat interfaces mtu is 1280 - 28 = 1252.

The ipv4 TCP MSS derived from that is 1252 - 20 ipv4 header
size - 20 tcp header size = 1212.

So, it's slightly safer to use an ipv4 advmss of 1212,
while we can use 1220 advmss for ipv6 (derived from
1280 ipv6 min guaranteed mtu - 40 ipv6 header - 20 tcp header)

While we're at it also slightly improve logging.

Test: TreeHugger
Signed-off-by: default avatarMaciej Żenczykowski <maze@google.com>
Change-Id: Iff8d5af1057998648b5b383ccf6912c6af2cdacf
parent d6df3afd
Loading
Loading
Loading
Loading
+13 −17
Original line number Diff line number Diff line
@@ -68,36 +68,32 @@ int waitForWriting(int fd, int timeoutMs = -1) {
}  // namespace

Status DnsTlsSocket::tcpConnect() {
    if (mServer.protocol != IPPROTO_TCP) return Status(EPROTONOSUPPORT);

    LOG(DEBUG) << mMark << " connecting TCP socket";
    int type = SOCK_NONBLOCK | SOCK_CLOEXEC;
    switch (mServer.protocol) {
        case IPPROTO_TCP:
            type |= SOCK_STREAM;
            break;
        default:
            return Status(EPROTONOSUPPORT);
    }

    mSslFd.reset(socket(mServer.ss.ss_family, type, mServer.protocol));
    mSslFd.reset(socket(mServer.ss.ss_family, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0));
    if (mSslFd.get() == -1) {
        PLOG(ERROR) << "Failed to create socket";
        return Status(errno);
        const int err = errno;
        PLOG(ERROR) << "Failed to create socket, errno=" << err;
        return Status(err);
    }

    resolv_tag_socket(mSslFd.get(), AID_DNS, NET_CONTEXT_INVALID_PID);

    const socklen_t len = sizeof(mMark);
    if (setsockopt(mSslFd.get(), SOL_SOCKET, SO_MARK, &mMark, len) == -1) {
    if (setsockopt(mSslFd.get(), SOL_SOCKET, SO_MARK, &mMark, len)) {
        const int err = errno;
        PLOG(ERROR) << "Failed to set socket mark";
        PLOG(ERROR) << "Failed to set socket mark, errno=" << err;
        mSslFd.reset();
        return Status(err);
    }

    // Set TCP MSS to a suitably low value to be more reliable.
    const int v = 1220;
    if (setsockopt(mSslFd.get(), SOL_TCP, TCP_MAXSEG, &v, sizeof(v)) == -1) {
        LOG(WARNING) << "Failed to set TCP_MAXSEG: " << errno;
    const int v = (mServer.ss.ss_family == AF_INET) ? 1212 : 1220;
    if (setsockopt(mSslFd.get(), SOL_TCP, TCP_MAXSEG, &v, sizeof(v))) {
        const int err = errno;
        LOG(WARNING) << "Failed to set TCP_MAXSEG, errno=" << err;
    }

    const Status tfo = enableSockopt(mSslFd.get(), SOL_TCP, TCP_FASTOPEN_CONNECT);
@@ -112,7 +108,7 @@ Status DnsTlsSocket::tcpConnect() {
                sizeof(mServer.ss)) != 0 &&
            errno != EINPROGRESS) {
        const int err = errno;
        PLOG(WARNING) << "Socket failed to connect";
        PLOG(WARNING) << "Socket failed to connect, errno=" << err;
        mSslFd.reset();
        return Status(err);
    }