diff options
| -rw-r--r-- | proxy-go/snowflake.go | 36 | ||||
| -rw-r--r-- | server/server.go | 17 |
2 files changed, 46 insertions, 7 deletions
diff --git a/proxy-go/snowflake.go b/proxy-go/snowflake.go index d25a491..4330dae 100644 --- a/proxy-go/snowflake.go +++ b/proxy-go/snowflake.go @@ -2,13 +2,13 @@ package main import ( "bytes" + "crypto/rand" "encoding/base64" "flag" "fmt" "io" "io/ioutil" "log" - "crypto/rand" "net" "net/http" "net/url" @@ -72,6 +72,24 @@ func (c *webRTCConn) LocalAddr() net.Addr { } func (c *webRTCConn) RemoteAddr() net.Addr { + //Parse Remote SDP offer and extract client IP + remoteSDP := c.pc.RemoteDescription().Sdp + splitSDP := strings.Split(remoteSDP, "\r\n") + for i := range splitSDP { + if strings.HasPrefix(splitSDP[i], "c=") { + candidSplit := strings.Split(splitSDP[i], " ") + if len(candidSplit) >= 3 { + addr := candidSplit[2] + + clientIP := net.ParseIP(addr) + if clientIP != nil { + // Return client IP address + clientAddr := &net.IPAddr{clientIP, ""} + return clientAddr + } + } + } + } return nil } @@ -182,7 +200,18 @@ func datachannelHandler(conn *webRTCConn) { defer conn.Close() defer retToken() - wsConn, err := websocket.Dial(opt.relay, "", opt.relay) + // Retrieve client IP address + if conn.RemoteAddr() != nil && conn.RemoteAddr().String() != "" { + // Encode client IP address in relay URL + q := opt.relayURL.Query() + clientIP := conn.RemoteAddr().String() + q.Set("client_ip", clientIP) + opt.relayURL.RawQuery = q.Encode() + } else { + log.Printf("no remote address given in websocket") + } + + wsConn, err := websocket.Dial(opt.relayURL.String(), "", opt.relay) if err != nil { log.Printf("error dialing relay: %s", err) return @@ -234,6 +263,7 @@ func makePeerConnectionFromOffer(sdp *webrtc.SessionDescription, config *webrtc. panic("short write") } } + conn := &webRTCConn{pc: pc, dc: dc, pr: pr} go datachannelHandler(conn) } @@ -307,7 +337,7 @@ func main() { log.SetFlags(log.LstdFlags | log.LUTC) if logFilename != "" { - f, err := os.OpenFile(logFilename, os.O_CREATE | os.O_WRONLY | os.O_APPEND, 0600) + f, err := os.OpenFile(logFilename, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600) if err != nil { log.Fatal(err) } diff --git a/server/server.go b/server/server.go index 3e29a0b..84ba414 100644 --- a/server/server.go +++ b/server/server.go @@ -139,10 +139,19 @@ func webSocketHandler(ws *websocket.WebSocket) { handlerChan <- -1 }() - // Pass an empty string for the client address. The remote address on - // the incoming connection reflects that of the browser proxy, not of - // the client. See https://bugs.torproject.org/18628. - or, err := pt.DialOr(&ptInfo, "", ptMethodName) + // Check if client addr is a valid IP + addr := ws.Request().URL.Query().Get("client_ip") + clientIP := net.ParseIP(addr) + + if clientIP == nil { + // Set client addr to empty + log.Printf("failed to validate client_ip: %s", addr) + addr = "" + } + + // Pass the address of client as the remote address of incoming connection + or, err := pt.DialOr(&ptInfo, addr, ptMethodName) + if err != nil { log.Printf("failed to connect to ORPort: %s", err) return |
