Skip to content

Commit 7e47667

Browse files
joliveirinhasssilver
authored andcommitted
TUN-5481: Create abstraction for Origin UDP Connection
Creates an abstraction over UDP Conn for origin "connection" which can be useful for future support of complex protocols that may require changing ports during protocol negotiation (eg. SIP, TFTP) In addition, it removes a dependency from ingress on connection package.
1 parent eea3d11 commit 7e47667

File tree

3 files changed

+47
-13
lines changed

3 files changed

+47
-13
lines changed

connection/quic.go

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
"golang.org/x/sync/errgroup"
1818

1919
"github.com/cloudflare/cloudflared/datagramsession"
20+
"github.com/cloudflare/cloudflared/ingress"
2021
quicpogs "github.com/cloudflare/cloudflared/quic"
2122
tunnelpogs "github.com/cloudflare/cloudflared/tunnelrpc/pogs"
2223
)
@@ -176,7 +177,7 @@ func (q *QUICConnection) handleRPCStream(rpcStream *quicpogs.RPCServerStream) er
176177
func (q *QUICConnection) RegisterUdpSession(ctx context.Context, sessionID uuid.UUID, dstIP net.IP, dstPort uint16) error {
177178
// Each session is a series of datagram from an eyeball to a dstIP:dstPort.
178179
// (src port, dst IP, dst port) uniquely identifies a session, so it needs a dedicated connected socket.
179-
originProxy, err := q.newUDPProxy(dstIP, dstPort)
180+
originProxy, err := ingress.DialUDP(dstIP, dstPort)
180181
if err != nil {
181182
q.logger.Err(err).Msgf("Failed to create udp proxy to %s:%d", dstIP, dstPort)
182183
return err
@@ -292,15 +293,6 @@ func isTransferEncodingChunked(req *http.Request) bool {
292293
return strings.Contains(strings.ToLower(transferEncodingVal), "chunked")
293294
}
294295

295-
// TODO: TUN-5303: Define an UDPProxy in ingress package
296-
func (q *QUICConnection) newUDPProxy(dstIP net.IP, dstPort uint16) (*net.UDPConn, error) {
297-
dstAddr := &net.UDPAddr{
298-
IP: dstIP,
299-
Port: int(dstPort),
300-
}
301-
return net.DialUDP("udp", nil, dstAddr)
302-
}
303-
304296
// TODO: TUN-5303: Find the local IP once in ingress package
305297
// TODO: TUN-5421 allow user to specify which IP to bind to
306298
func getLocalIP() (net.IP, error) {

ingress/origin_connection_test.go

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"bytes"
55
"context"
66
"fmt"
7+
"io"
78
"io/ioutil"
89
"net"
910
"net/http"
@@ -19,7 +20,6 @@ import (
1920
"golang.org/x/net/proxy"
2021
"golang.org/x/sync/errgroup"
2122

22-
"github.com/cloudflare/cloudflared/connection"
2323
"github.com/cloudflare/cloudflared/logger"
2424
"github.com/cloudflare/cloudflared/socks"
2525
"github.com/cloudflare/cloudflared/websocket"
@@ -192,8 +192,10 @@ func TestSocksStreamWSOverTCPConnection(t *testing.T) {
192192

193193
func TestWsConnReturnsBeforeStreamReturns(t *testing.T) {
194194
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
195-
eyeballConn, err := connection.NewHTTP2RespWriter(r, w, connection.TypeWebsocket)
196-
assert.NoError(t, err)
195+
eyeballConn := &readWriter{
196+
w: w,
197+
r: r.Body,
198+
}
197199

198200
cfdConn, originConn := net.Pipe()
199201
tcpOverWSConn := tcpOverWSConnection{
@@ -319,3 +321,16 @@ func echoTCPOrigin(t *testing.T, conn net.Conn) {
319321
_, err = conn.Write(testResponse)
320322
assert.NoError(t, err)
321323
}
324+
325+
type readWriter struct {
326+
w io.Writer
327+
r io.Reader
328+
}
329+
330+
func (r *readWriter) Read(p []byte) (n int, err error) {
331+
return r.r.Read(p)
332+
}
333+
334+
func (r *readWriter) Write(p []byte) (n int, err error) {
335+
return r.w.Write(p)
336+
}

ingress/origin_udp_proxy.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package ingress
2+
3+
import (
4+
"fmt"
5+
"io"
6+
"net"
7+
)
8+
9+
type UDPProxy struct {
10+
io.ReadWriteCloser
11+
}
12+
13+
func DialUDP(dstIP net.IP, dstPort uint16) (*UDPProxy, error) {
14+
dstAddr := &net.UDPAddr{
15+
IP: dstIP,
16+
Port: int(dstPort),
17+
}
18+
19+
// We use nil as local addr to force runtime to find the best suitable local address IP given the destination
20+
// address as context.
21+
udpConn, err := net.DialUDP("udp", nil, dstAddr)
22+
if err != nil {
23+
return nil, fmt.Errorf("unable to create UDP proxy to origin (%v:%v): %w", dstIP, dstPort, err)
24+
}
25+
26+
return &UDPProxy{udpConn}, nil
27+
}

0 commit comments

Comments
 (0)