Handle generated errors in server-webrtc

This commit is contained in:
Shane Howearth 2019-09-26 09:19:22 +10:00 committed by Cecylia Bocovich
parent 82e5753bcc
commit 3ec9dd19fa
3 changed files with 57 additions and 22 deletions

View file

@ -13,7 +13,7 @@ const (
SnowflakeTimeout = 30 SnowflakeTimeout = 30
) )
// When a connection handler starts, +1 is written to this channel; when it // HandlerChan - When a connection handler starts, +1 is written to this channel; when it
// ends, -1 is written. // ends, -1 is written.
var HandlerChan = make(chan int) var HandlerChan = make(chan int)
@ -27,7 +27,10 @@ func Handler(socks SocksConnector, snowflakes SnowflakeCollector) error {
// Obtain an available WebRTC remote. May block. // Obtain an available WebRTC remote. May block.
snowflake := snowflakes.Pop() snowflake := snowflakes.Pop()
if nil == snowflake { if nil == snowflake {
socks.Reject() if err := socks.Reject(); err != nil {
log.Printf("socks.Reject returned error: %v", err)
}
return errors.New("handler: Received invalid Snowflake") return errors.New("handler: Received invalid Snowflake")
} }
defer socks.Close() defer socks.Close()
@ -57,11 +60,15 @@ func copyLoop(a, b io.ReadWriter) {
var wg sync.WaitGroup var wg sync.WaitGroup
wg.Add(2) wg.Add(2)
go func() { go func() {
io.Copy(b, a) if _, err := io.Copy(ORPort, WebRTC); err != nil {
log.Printf("copying WebRTC to ORPort resulted in error: %v", err)
}
wg.Done() wg.Done()
}() }()
go func() { go func() {
io.Copy(a, b) if _, err := io.Copy(WebRTC, ORPort); err != nil {
log.Printf("copying ORPort to WebRTC resulted in error: %v", err)
}
wg.Done() wg.Done()
}() }()
wg.Wait() wg.Wait()

View file

@ -23,11 +23,14 @@ func (h *httpHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
case "GET": case "GET":
w.Header().Set("Content-Type", "text/plain; charset=utf-8") w.Header().Set("Content-Type", "text/plain; charset=utf-8")
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
w.Write([]byte(`HTTP signaling channel _, err := w.Write([]byte(`HTTP signaling channel
Send a POST request containing an SDP offer. The response will Send a POST request containing an SDP offer. The response will
contain an SDP answer. contain an SDP answer.
`)) `))
if err != nil {
log.Printf("GET request write failed with error: %v", err)
}
return return
case "POST": case "POST":
break break
@ -57,7 +60,11 @@ contain an SDP answer.
log.Println("answering HTTP POST") log.Println("answering HTTP POST")
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
w.Write([]byte(pc.LocalDescription().Serialize())) _, err = w.Write([]byte(pc.LocalDescription().Serialize()))
if err != nil {
log.Printf("answering HTTP POST write failed with error %v", err)
}
} }
func receiveSignalsHTTP(addr string, config *webrtc.Configuration) error { func receiveSignalsHTTP(addr string, config *webrtc.Configuration) error {

View file

@ -13,7 +13,7 @@ import (
"syscall" "syscall"
"time" "time"
"git.torproject.org/pluggable-transports/goptlib.git" pt "git.torproject.org/pluggable-transports/goptlib.git"
"github.com/keroserene/go-webrtc" "github.com/keroserene/go-webrtc"
) )
@ -25,15 +25,19 @@ var logFile *os.File
// when it ends, -1 is written. // when it ends, -1 is written.
var handlerChan = make(chan int) var handlerChan = make(chan int)
func copyLoop(a, b net.Conn) { func copyLoop(WebRTC, ORPort net.Conn) {
var wg sync.WaitGroup var wg sync.WaitGroup
wg.Add(2) wg.Add(2)
go func() { go func() {
io.Copy(b, a) if _, err := io.Copy(ORPort, WebRTC); err != nil {
log.Printf("copy WebRTC to ORPort error in copyLoop: %v", err)
}
wg.Done() wg.Done()
}() }()
go func() { go func() {
io.Copy(a, b) if _, err := io.Copy(WebRTC, ORPort); err != nil {
log.Printf("copy ORPort to WebRTC error in copyLoop: %v", err)
}
wg.Done() wg.Done()
}() }()
wg.Wait() wg.Wait()
@ -79,14 +83,17 @@ func (c *webRTCConn) RemoteAddr() net.Addr {
} }
func (c *webRTCConn) SetDeadline(t time.Time) error { func (c *webRTCConn) SetDeadline(t time.Time) error {
// nolint:golint
return fmt.Errorf("SetDeadline not implemented") return fmt.Errorf("SetDeadline not implemented")
} }
func (c *webRTCConn) SetReadDeadline(t time.Time) error { func (c *webRTCConn) SetReadDeadline(t time.Time) error {
// nolint:golint
return fmt.Errorf("SetReadDeadline not implemented") return fmt.Errorf("SetReadDeadline not implemented")
} }
func (c *webRTCConn) SetWriteDeadline(t time.Time) error { func (c *webRTCConn) SetWriteDeadline(t time.Time) error {
// nolint:golint
return fmt.Errorf("SetWriteDeadline not implemented") return fmt.Errorf("SetWriteDeadline not implemented")
} }
@ -139,9 +146,12 @@ func makePeerConnectionFromOffer(sdp *webrtc.SessionDescription, config *webrtc.
} }
dc.OnMessage = func(msg []byte) { dc.OnMessage = func(msg []byte) {
log.Printf("OnMessage <--- %d bytes", len(msg)) log.Printf("OnMessage <--- %d bytes", len(msg))
n, err := pw.Write(msg) var n int
n, err = pw.Write(msg)
if err != nil { if err != nil {
pw.CloseWithError(err) if inerr := pw.CloseWithError(err); inerr != nil {
log.Printf("close with error returned error: %v", inerr)
}
} }
if n != len(msg) { if n != len(msg) {
panic("short write") panic("short write")
@ -153,7 +163,9 @@ func makePeerConnectionFromOffer(sdp *webrtc.SessionDescription, config *webrtc.
err = pc.SetRemoteDescription(sdp) err = pc.SetRemoteDescription(sdp)
if err != nil { if err != nil {
pc.Destroy() if err = pc.Destroy(); err != nil {
log.Printf("pc.Destroy returned an error: %v", err)
}
return nil, fmt.Errorf("accept: SetRemoteDescription: %s", err) return nil, fmt.Errorf("accept: SetRemoteDescription: %s", err)
} }
log.Println("sdp offer successfully received.") log.Println("sdp offer successfully received.")
@ -161,18 +173,24 @@ func makePeerConnectionFromOffer(sdp *webrtc.SessionDescription, config *webrtc.
log.Println("Generating answer...") log.Println("Generating answer...")
answer, err := pc.CreateAnswer() answer, err := pc.CreateAnswer()
if err != nil { if err != nil {
pc.Destroy() if err = pc.Destroy(); err != nil {
log.Printf("pc.Destroy returned an error: %v", err)
}
return nil, err return nil, err
} }
if answer == nil { if answer == nil {
pc.Destroy() if err = pc.Destroy(); err != nil {
return nil, fmt.Errorf("Failed gathering ICE candidates.") log.Printf("pc.Destroy returned an error: %v", err)
}
return nil, fmt.Errorf("failed gathering ICE candidates")
} }
err = pc.SetLocalDescription(answer) err = pc.SetLocalDescription(answer)
if err != nil { if err != nil {
pc.Destroy() if err = pc.Destroy(); err != nil {
log.Printf("pc.Destroy returned an error: %v", err)
}
return nil, err return nil, err
} }
@ -180,7 +198,6 @@ func makePeerConnectionFromOffer(sdp *webrtc.SessionDescription, config *webrtc.
} }
func main() { func main() {
var err error
var httpAddr string var httpAddr string
var logFilename string var logFilename string
@ -200,7 +217,7 @@ func main() {
log.Println("starting") log.Println("starting")
webrtc.SetLoggingVerbosity(1) webrtc.SetLoggingVerbosity(1)
var err error
ptInfo, err = pt.ServerSetup(nil) ptInfo, err = pt.ServerSetup(nil)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
@ -222,12 +239,14 @@ func main() {
bindaddr.Addr.Port = 12345 // lies!!! bindaddr.Addr.Port = 12345 // lies!!!
pt.Smethod(bindaddr.MethodName, bindaddr.Addr) pt.Smethod(bindaddr.MethodName, bindaddr.Addr)
default: default:
pt.SmethodError(bindaddr.MethodName, "no such method") if err := pt.SmethodError(bindaddr.MethodName, "no such method"); err != nil {
log.Printf("SmethodError returned error: %v", err)
}
} }
} }
pt.SmethodsDone() pt.SmethodsDone()
var numHandlers int = 0 var numHandlers int
var sig os.Signal var sig os.Signal
sigChan := make(chan os.Signal, 1) sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGTERM) signal.Notify(sigChan, syscall.SIGTERM)
@ -236,7 +255,9 @@ func main() {
// This environment variable means we should treat EOF on stdin // This environment variable means we should treat EOF on stdin
// just like SIGTERM: https://bugs.torproject.org/15435. // just like SIGTERM: https://bugs.torproject.org/15435.
go func() { go func() {
io.Copy(ioutil.Discard, os.Stdin) if _, err := io.Copy(ioutil.Discard, os.Stdin); err != nil {
log.Printf("error copying os.Stdin to ioutil.Discard: %v", err)
}
log.Printf("synthesizing SIGTERM because of stdin close") log.Printf("synthesizing SIGTERM because of stdin close")
sigChan <- syscall.SIGTERM sigChan <- syscall.SIGTERM
}() }()