@@ -13,13 +13,20 @@ import (
1313)
1414
1515var (
16- reservedHost = "coder"
17- credential = "coder"
16+ // reservedAddress is a magic address that's used exclusively
17+ // for proxying via Coder. We don't proxy all TURN connections,
18+ // because that'd exclude the possibility of a customer using
19+ // their own TURN server.
20+ reservedAddress = "127.0.0.1:12345"
21+ credential = "coder"
22+ localhost = & net.TCPAddr {
23+ IP : net .IPv4 (127 , 0 , 0 , 1 ),
24+ }
1825
1926 // Proxy is a an ICE Server that uses a special hostname
2027 // to indicate traffic should be proxied.
2128 Proxy = webrtc.ICEServer {
22- URLs : []string {"turns:" + reservedHost },
29+ URLs : []string {"turns:" + reservedAddress },
2330 Username : "coder" ,
2431 Credential : credential ,
2532 }
@@ -29,14 +36,32 @@ var (
2936// The relay address is used to broadcast the location of an accepted connection.
3037func New (relayAddress * turn.RelayAddressGeneratorStatic ) (* Server , error ) {
3138 if relayAddress == nil {
32- // Default to localhost.
39+ ip := "127.0.0.1"
40+ addrs , err := net .InterfaceAddrs ()
41+ if err != nil {
42+ return nil , xerrors .Errorf ("find interface addrs: %w" , err )
43+ }
44+ // Try to find the localhost IP address.
45+ // It will generally be 127.0.0.1, but
46+ // search to be sure!
47+ for _ , address := range addrs {
48+ ipNet , ok := address .(* net.IPNet )
49+ if ! ok {
50+ continue
51+ }
52+ if ! ipNet .IP .IsLoopback () {
53+ continue
54+ }
55+ ip = ipNet .IP .String ()
56+ break
57+ }
3358 relayAddress = & turn.RelayAddressGeneratorStatic {
34- RelayAddress : net.IP { 127 , 0 , 0 , 1 } ,
35- Address : "127.0.0.1" ,
59+ RelayAddress : net .ParseIP ( ip ) ,
60+ Address : ip ,
3661 }
3762 }
3863 logger := logging .NewDefaultLoggerFactory ()
39- logger .DefaultLogLevel = logging .LogLevelDisabled
64+ logger .DefaultLogLevel = logging .LogLevelDebug
4065 server := & Server {
4166 conns : make (chan net.Conn , 1 ),
4267 closed : make (chan struct {}),
@@ -47,6 +72,8 @@ func New(relayAddress *turn.RelayAddressGeneratorStatic) (*Server, error) {
4772 var err error
4873 server .turn , err = turn .NewServer (turn.ServerConfig {
4974 AuthHandler : func (username , realm string , srcAddr net.Addr ) (key []byte , ok bool ) {
75+ // TURN connections require credentials. It's not important
76+ // for our use-case, because our listener is entirely in-memory.
5077 return turn .GenerateAuthKey (Proxy .Username , "" , credential ), true
5178 },
5279 ListenerConfigs : []turn.ListenerConfig {{
@@ -62,33 +89,6 @@ func New(relayAddress *turn.RelayAddressGeneratorStatic) (*Server, error) {
6289 return server , nil
6390}
6491
65- // ProxyDialer accepts a proxy function that's called when the connection
66- // address matches the reserved host in the "Proxy" ICE server.
67- //
68- // This should be passed to WebRTC connections as an ICE dialer.
69- func ProxyDialer (proxyFunc func () (c net.Conn , err error )) proxy.Dialer {
70- return dialer (func (network , addr string ) (net.Conn , error ) {
71- host , _ , err := net .SplitHostPort (addr )
72- if err != nil {
73- return nil , err
74- }
75- if host != reservedHost {
76- return proxy .Direct .Dial (network , addr )
77- }
78- netConn , err := proxyFunc ()
79- if err != nil {
80- return nil , err
81- }
82- return & Conn {
83- localAddress : & net.TCPAddr {
84- IP : net .IPv4 (127 , 0 , 0 , 1 ),
85- },
86- closed : make (chan struct {}),
87- Conn : netConn ,
88- }, nil
89- })
90- }
91-
9292// Server accepts and connects TURN allocations.
9393//
9494// This is a thin wrapper around pion/turn that pipes
@@ -105,10 +105,14 @@ type Server struct {
105105// Accept consumes a new connection into the TURN server.
106106// A unique remote address must exist per-connection.
107107// pion/turn indexes allocations based on the address.
108- func (s * Server ) Accept (nc net.Conn , remoteAddress * net.TCPAddr ) * Conn {
108+ func (s * Server ) Accept (nc net.Conn , remoteAddress , localAddress * net.TCPAddr ) * Conn {
109+ if localAddress == nil {
110+ localAddress = localhost
111+ }
109112 conn := & Conn {
110113 Conn : nc ,
111114 remoteAddress : remoteAddress ,
115+ localAddress : localAddress ,
112116 closed : make (chan struct {}),
113117 }
114118 s .conns <- conn
@@ -181,16 +185,38 @@ func (c *Conn) Closed() <-chan struct{} {
181185}
182186
183187func (c * Conn ) Close () error {
188+ err := c .Conn .Close ()
184189 select {
185190 case <- c .closed :
186191 default :
187192 close (c .closed )
188193 }
189- return c . Conn . Close ()
194+ return err
190195}
191196
192197type dialer func (network , addr string ) (c net.Conn , err error )
193198
194199func (d dialer ) Dial (network , addr string ) (c net.Conn , err error ) {
195200 return d (network , addr )
196201}
202+
203+ // ProxyDialer accepts a proxy function that's called when the connection
204+ // address matches the reserved host in the "Proxy" ICE server.
205+ //
206+ // This should be passed to WebRTC connections as an ICE dialer.
207+ func ProxyDialer (proxyFunc func () (c net.Conn , err error )) proxy.Dialer {
208+ return dialer (func (network , addr string ) (net.Conn , error ) {
209+ if addr != reservedAddress {
210+ return proxy .Direct .Dial (network , addr )
211+ }
212+ netConn , err := proxyFunc ()
213+ if err != nil {
214+ return nil , err
215+ }
216+ return & Conn {
217+ localAddress : localhost ,
218+ closed : make (chan struct {}),
219+ Conn : netConn ,
220+ }, nil
221+ })
222+ }
0 commit comments