MCPcopy
hub / github.com/cloudflare/cloudflared / createUDPConnForConnIndex

Function createUDPConnForConnIndex

connection/quic.go:50–95  ·  view source on GitHub ↗
(connIndex uint8, localIP net.IP, edgeIP netip.AddrPort, opts dialopts.DialOpts, logger *zerolog.Logger)

Source from the content-addressed store, hash-verified

48}
49
50func createUDPConnForConnIndex(connIndex uint8, localIP net.IP, edgeIP netip.AddrPort, opts dialopts.DialOpts, logger *zerolog.Logger) (*net.UDPConn, error) {
51 listenNetwork := "udp"
52 // https://github.com/quic-go/quic-go/issues/3793 DF bit cannot be set for dual stack listener ("udp") on macOS,
53 // to set the DF bit properly, the network string needs to be specific to the IP family.
54 if runtime.GOOS == "darwin" {
55 if edgeIP.Addr().Is4() {
56 listenNetwork = "udp4"
57 } else {
58 listenNetwork = "udp6"
59 }
60 }
61
62 // Probes skip port reuse entirely to avoid interfering with the main connection flow.
63 // They use a random ephemeral port for each dial.
64 if opts.SkipPortReuse {
65 return net.ListenUDP(listenNetwork, &net.UDPAddr{IP: localIP, Port: 0})
66 }
67
68 portMapMutex.Lock()
69 defer portMapMutex.Unlock()
70
71 // if port was not set yet, it will be zero, so bind will randomly allocate one.
72 if port, ok := portForConnIndex[connIndex]; ok {
73 udpConn, err := net.ListenUDP(listenNetwork, &net.UDPAddr{IP: localIP, Port: port})
74 // if there wasn't an error, or if port was 0 (independently of error or not, just return)
75 if err == nil {
76 return udpConn, nil
77 }
78
79 logger.Debug().Err(err).Msgf("Unable to reuse port %d for connIndex %d. Falling back to random allocation.", port, connIndex)
80 }
81
82 // if we reached here, then there was an error or port as not been allocated it.
83 udpConn, err := net.ListenUDP(listenNetwork, &net.UDPAddr{IP: localIP, Port: 0})
84 if err == nil {
85 udpAddr, ok := (udpConn.LocalAddr()).(*net.UDPAddr)
86 if !ok {
87 return nil, fmt.Errorf("unable to cast to udpConn")
88 }
89 portForConnIndex[connIndex] = udpAddr.Port
90 } else {
91 delete(portForConnIndex, connIndex)
92 }
93
94 return udpConn, err
95}

Callers 3

TestSkipPortReuseFunction · 0.85
DialQuicFunction · 0.85

Calls 4

AddrMethod · 0.80
ErrorfMethod · 0.80
LocalAddrMethod · 0.65
ErrMethod · 0.45

Tested by 2

TestSkipPortReuseFunction · 0.68