summaryrefslogtreecommitdiffstats
path: root/lib/connections/quic_misc.go
blob: 37758f2e00e46b835dbde73b0b1723ede5fe768d (plain)
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
// Copyright (C) 2019 The Syncthing Authors.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at http://mozilla.org/MPL/2.0/.

// +build go1.12

package connections

import (
	"net"

	"github.com/lucas-clemente/quic-go"
)

var (
	quicConfig = &quic.Config{
		ConnectionIDLength: 4,
		KeepAlive:          true,
	}
)

type quicTlsConn struct {
	quic.Session
	quic.Stream
	// If we created this connection, we should be the ones closing it.
	createdConn net.PacketConn
}

func (q *quicTlsConn) Close() error {
	sterr := q.Stream.Close()
	seerr := q.Session.Close()
	var pcerr error
	if q.createdConn != nil {
		pcerr = q.createdConn.Close()
	}
	if sterr != nil {
		return sterr
	}
	if seerr != nil {
		return seerr
	}
	return pcerr
}

// Sort available packet connections by ip address, preferring unspecified local address.
func packetConnLess(i interface{}, j interface{}) bool {
	iIsUnspecified := false
	jIsUnspecified := false
	iLocalAddr := i.(net.PacketConn).LocalAddr()
	jLocalAddr := j.(net.PacketConn).LocalAddr()

	if host, _, err := net.SplitHostPort(iLocalAddr.String()); err == nil {
		iIsUnspecified = host == "" || net.ParseIP(host).IsUnspecified()
	}
	if host, _, err := net.SplitHostPort(jLocalAddr.String()); err == nil {
		jIsUnspecified = host == "" || net.ParseIP(host).IsUnspecified()
	}

	if jIsUnspecified == iIsUnspecified {
		return len(iLocalAddr.Network()) < len(jLocalAddr.Network())
	}

	return iIsUnspecified
}