Skip to content

Commit

Permalink
add tcp over tls and wss acceptors
Browse files Browse the repository at this point in the history
  • Loading branch information
felipejfc committed Apr 10, 2018
1 parent f4847f1 commit 1825b59
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 15 deletions.
21 changes: 21 additions & 0 deletions acceptor/fixtures/server.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDdDCCAlwCCQDfEyb9MASNvjANBgkqhkiG9w0BAQsFADB8MQswCQYDVQQGEwJC
UjELMAkGA1UECAwCU1AxCzAJBgNVBAcMAlNQMQ8wDQYDVQQKDAZQaXRheWExEDAO
BgNVBAsMB0JhY2tlbmQxEjAQBgNVBAMMCWxvY2FsaG9zdDEcMBoGCSqGSIb3DQEJ
ARYNcGl0YXlhQHBpdGF5YTAeFw0xODA0MTAyMjEwMTNaFw0yODA0MDcyMjEwMTNa
MHwxCzAJBgNVBAYTAkJSMQswCQYDVQQIDAJTUDELMAkGA1UEBwwCU1AxDzANBgNV
BAoMBlBpdGF5YTEQMA4GA1UECwwHQmFja2VuZDESMBAGA1UEAwwJbG9jYWxob3N0
MRwwGgYJKoZIhvcNAQkBFg1waXRheWFAcGl0YXlhMIIBIjANBgkqhkiG9w0BAQEF
AAOCAQ8AMIIBCgKCAQEArUveZUOOW2Yl92KpvaAYCwjGy3krUbeSEC0m/FbogWz6
3PhFNsobKwp4z8UrgJEGQJZTpA4XU4O1MIw9f+u7qbdJxn4sM9aeYyw5ks7VdgdQ
Wy70EJ2qOElhq2I7n0/Dg6cYmOVYif4BHq5mlVYCujKcpsU+bscPaTqxHu+/4QUH
cBAkcm6nC2ucRZsSdTD/M5uxatSjJK6ustgUN3TLMzFSRC6/kvS2/dwIgWeePnID
nFZaAWxq4tlE3oG2aIH7oRMSDpRj29d9DjvoQUPSdnADbkq6+n3GKPPqLo3ArQxx
gvfKKQFgGyTtTUKZQ95BJCFE+SDIxTc/9YxcTsdxDQIDAQABMA0GCSqGSIb3DQEB
CwUAA4IBAQApWiKBLHDrDuwUMS1OESzr1obWesaA3hGXtgEn31+tr0bNeV1F/ZjZ
KhUBGm4kcLERuc7w+J268PDyU3C8tf4ar5NFgAbUgfE2mD6+LGTsSdS06fJVakjl
v1i4mK6eijC3XkWyP8yIVJRSn+uvR7PGXmRFJoQIv96y918UYLgwvh/do4P/JZYy
VNR99XvznijV7Hq0aP4W742PjWjj5/cPFnRJOMNPKFupZvYaKWVv2c1IO4HKkCQ4
FRyO6PIxgNDGOz8Bkc4Z7CMbOyBRpElvOFAE5hsxIufn8DgRkQahfiBOjqpSHq73
eyuaAd8sURZSDx8ToT2loVh+dlSsqtNI
-----END CERTIFICATE-----
28 changes: 28 additions & 0 deletions acceptor/fixtures/server.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtS95lQ45bZiX3
Yqm9oBgLCMbLeStRt5IQLSb8VuiBbPrc+EU2yhsrCnjPxSuAkQZAllOkDhdTg7Uw
jD1/67upt0nGfiwz1p5jLDmSztV2B1BbLvQQnao4SWGrYjufT8ODpxiY5ViJ/gEe
rmaVVgK6MpymxT5uxw9pOrEe77/hBQdwECRybqcLa5xFmxJ1MP8zm7Fq1KMkrq6y
2BQ3dMszMVJELr+S9Lb93AiBZ54+cgOcVloBbGri2UTegbZogfuhExIOlGPb130O
O+hBQ9J2cANuSrr6fcYo8+oujcCtDHGC98opAWAbJO1NQplD3kEkIUT5IMjFNz/1
jFxOx3ENAgMBAAECggEBAIglsvObv5vPBMT2nqR7wmfo3UW+TGpG7loHHzngjYoh
NHWmF7qTzgRilcemACdhyKe1csDQ0UKrlw4tH6QAb89GUI/BULjpREZl2FWeadXw
qRD6MoVbWQAfprwe0Pi4kcI85PY6OPUwuXCBU9a/XCUs3iWnkQU3HsRtd/n2IamG
HooKGz5Ij1+FaB2dKUiwYvxsdA9w2Yg54VuuLce/6VgnR79eYEseGvN44Y68JAsU
nwzsXv9eVmn8T22/uWaaDPOaIwysVNI5YI+WyfcI9HQIaJxVAPggoZh4N6pnD6UM
BjI+EJWD3Aiq1Z6CDG4c2FV4Ku0f/l456ykvZrosbAECgYEA3eMTLC0l7H+Msndz
aUzimKqstPKBWqyJ3Z6sXYGO26/z3mZjcl1+A4gZGWegptMk6PsP27jevWRVPuNi
o/eagGcJ3wpNISkwoJgvkhPDmFSFH+d74yCQQRgPsuJbyaHX+RiDTj4sWgBWoq+T
UR9GQxFmGObklMmBF0o/VeU9XjUCgYEAx/BixVC4gvqBKZdlhLF8e6HWFXhNCIsj
0H6I5vgtSex8I/Zsy320kA0hfzZEuaaGVNrQiYWBAAdAwTKS3W13X8ryBDS6mrCs
BKuM7PDJrS4vKVmiTqMwDpEpL/c9SoOCiPiseZeteoHfKkVsPoQrc2bQzvfttQa6
aHRvyjkTgnkCgYByYbRoeX2rRLVK6rjb9354JMOTI8/65ibL0Bgau8bhCPs2EqIB
OqDTQT1vEzSFyyKj14h9Q/fOugIXwTAARoum1XcJO043YfxnTQx4ySdzR16466O5
mffDFpxBIt8eOggTqMdHdlV2r+X5R3kxwGV//WAcRipfaODbGLM9nEbeYQKBgQCL
JJ8IZLHT7VQARu2OmBpiy/D6RhuOK48EJVtPKj4SaTLHsFJsl5IWghzitDjF3r8z
xIhGfJOXGnUVPwX4dZsTHmCpTqzixLsiEOVla/levXpy039iLK1gJeO9DtonxjgM
7MrTYByJ2mIdv+yh4Ud/63i74M0cI4+M7CN0X55VOQKBgDw0A5cdenE5VIH2nEsx
SWQ8nSz2qli+59sUcRfDnAWT7iJ5DCzxOVV+wQ/A3D/SbufWJQZpJBSJlXnyY1BX
qFiOrseNsU2R0EDmi8agdgVBqxX/NmF9+Np0G3dFyoeYI68BwpiteCa/Aw2HzPl5
2SJrVnL52ZOK5WAumUbuWQqA
-----END PRIVATE KEY-----
23 changes: 22 additions & 1 deletion acceptor/tcp_acceptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
package acceptor

import (
"crypto/tls"
"net"

"github.com/topfreegames/pitaya/logger"
Expand Down Expand Up @@ -72,13 +73,33 @@ func (a *TCPAcceptor) ListenAndServe() {
}
a.listener = listener
a.running = true
a.serve()
}

// ListenAndServeTLS listens using tls
func (a *TCPAcceptor) ListenAndServeTLS(cert, key string) {
crt, err := tls.LoadX509KeyPair(cert, key)
if err != nil {
log.Fatal(err)
}

tlsCfg := &tls.Config{Certificates: []tls.Certificate{crt}}

listener, err := tls.Listen("tcp", a.addr, tlsCfg)
a.listener = listener
a.running = true
a.serve()
}

func (a *TCPAcceptor) serve() {
defer a.Stop()
for a.running {
conn, err := listener.Accept()
conn, err := a.listener.Accept()
if err != nil {
log.Error(err.Error())
continue
}
a.connChan <- conn
}

}
22 changes: 21 additions & 1 deletion acceptor/tcp_acceptor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func TestGetConnChan(t *testing.T) {
}
}

func TestListenAndServer(t *testing.T) {
func TestListenAndServe(t *testing.T) {
for _, table := range tcpAcceptorTables {
t.Run(table.name, func(t *testing.T) {
a := NewTCPAcceptor(table.addr)
Expand All @@ -88,6 +88,26 @@ func TestListenAndServer(t *testing.T) {
}
}

func TestListenAndServeTLS(t *testing.T) {
for _, table := range tcpAcceptorTables {
t.Run(table.name, func(t *testing.T) {
a := NewTCPAcceptor(table.addr)
defer a.Stop()
c := a.GetConnChan()

go a.ListenAndServeTLS("./fixtures/server.crt", "./fixtures/server.key")
// should be able to connect within 100 milliseconds
helpers.ShouldEventuallyReturn(t, func() error {
n, err := net.Dial("tcp", a.GetAddr())
defer n.Close()
return err
}, nil, 10*time.Millisecond, 100*time.Millisecond)
conn := helpers.ShouldEventuallyReceive(t, c, 100*time.Millisecond)
assert.NotNil(t, conn)
})
}
}

func TestStop(t *testing.T) {
for _, table := range tcpAcceptorTables {
t.Run(table.name, func(t *testing.T) {
Expand Down
31 changes: 28 additions & 3 deletions acceptor/ws_acceptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
package acceptor

import (
"crypto/tls"
"io"
"net"
"net/http"
Expand Down Expand Up @@ -92,13 +93,37 @@ func (w *WSAcceptor) ListenAndServe() {
}
w.listener = listener

w.serve(&upgrader)
}

// ListenAndServeTLS listens and serve in the specified addr using tls
func (w *WSAcceptor) ListenAndServeTLS(cert, key string) {
var upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
}

crt, err := tls.LoadX509KeyPair(cert, key)
if err != nil {
log.Fatal(err)
}

tlsCfg := &tls.Config{Certificates: []tls.Certificate{crt}}
listener, err := tls.Listen("tcp", w.addr, tlsCfg)
if err != nil {
log.Fatal(err)
}
w.listener = listener
w.serve(&upgrader)
}

func (w *WSAcceptor) serve(upgrader *websocket.Upgrader) {
defer w.Stop()

http.Serve(listener, &connHandler{
upgrader: &upgrader,
http.Serve(w.listener, &connHandler{
upgrader: upgrader,
connChan: w.connChan,
})

}

// Stop stops the acceptor
Expand Down
39 changes: 29 additions & 10 deletions acceptor/ws_acceptor_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package acceptor

import (
"crypto/tls"
"fmt"
"testing"
"time"
Expand Down Expand Up @@ -51,10 +52,13 @@ func TestWSAcceptorGetConn(t *testing.T) {
}
}

func mustConnectToWS(t *testing.T, write []byte, w *WSAcceptor) {
func mustConnectToWS(t *testing.T, write []byte, w *WSAcceptor, protocol string) {
t.Helper()
helpers.ShouldEventuallyReturn(t, func() error {
addr := fmt.Sprintf("ws://%s", w.GetAddr())
conn, _, err := websocket.DefaultDialer.Dial(addr, nil)
addr := fmt.Sprintf("%s://%s", protocol, w.GetAddr())
dialer := websocket.DefaultDialer
conn, _, err := dialer.Dial(addr, nil)
dialer.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
conn.WriteMessage(websocket.BinaryMessage, write)
defer conn.Close()
return err
Expand All @@ -68,7 +72,22 @@ func TestWSAcceptorListenAndServe(t *testing.T) {
c := w.GetConnChan()
defer w.Stop()
go w.ListenAndServe()
mustConnectToWS(t, table.write, w)
mustConnectToWS(t, table.write, w, "ws")
conn := helpers.ShouldEventuallyReceive(t, c, 100*time.Millisecond).(*wsConn)
defer conn.Close()
assert.NotNil(t, conn)
})
}
}

func TestWSAcceptorListenAndServeTLS(t *testing.T) {
for _, table := range wsAcceptorTables {
t.Run(table.name, func(t *testing.T) {
w := NewWSAcceptor(table.addr)
c := w.GetConnChan()
defer w.Stop()
go w.ListenAndServeTLS("./fixtures/server.crt", "./fixtures/server.key")
mustConnectToWS(t, table.write, w, "wss")
conn := helpers.ShouldEventuallyReceive(t, c, 100*time.Millisecond).(*wsConn)
defer conn.Close()
assert.NotNil(t, conn)
Expand All @@ -81,7 +100,7 @@ func TestWSAcceptorStop(t *testing.T) {
t.Run(table.name, func(t *testing.T) {
w := NewWSAcceptor(table.addr)
go w.ListenAndServe()
mustConnectToWS(t, table.write, w)
mustConnectToWS(t, table.write, w, "ws")
addr := fmt.Sprintf("ws://%s", w.GetAddr())
w.Stop()
_, _, err := websocket.DefaultDialer.Dial(addr, nil)
Expand All @@ -97,7 +116,7 @@ func TestWSConnRead(t *testing.T) {
c := w.GetConnChan()
defer w.Stop()
go w.ListenAndServe()
mustConnectToWS(t, table.write, w)
mustConnectToWS(t, table.write, w, "ws")
conn := helpers.ShouldEventuallyReceive(t, c, 100*time.Millisecond).(*wsConn)
defer conn.Close()
b := make([]byte, len(table.write))
Expand All @@ -116,7 +135,7 @@ func TestWSConnWrite(t *testing.T) {
c := w.GetConnChan()
defer w.Stop()
go w.ListenAndServe()
mustConnectToWS(t, table.write, w)
mustConnectToWS(t, table.write, w, "ws")
conn := helpers.ShouldEventuallyReceive(t, c, 100*time.Millisecond).(*wsConn)
defer conn.Close()
b := make([]byte, len(table.write))
Expand All @@ -134,7 +153,7 @@ func TestWSConnLocalAddr(t *testing.T) {
c := w.GetConnChan()
defer w.Stop()
go w.ListenAndServe()
mustConnectToWS(t, table.write, w)
mustConnectToWS(t, table.write, w, "ws")
conn := helpers.ShouldEventuallyReceive(t, c, 100*time.Millisecond).(*wsConn)
defer conn.Close()
a := conn.LocalAddr().String()
Expand All @@ -150,7 +169,7 @@ func TestWSConnRemoteAddr(t *testing.T) {
c := w.GetConnChan()
defer w.Stop()
go w.ListenAndServe()
mustConnectToWS(t, table.write, w)
mustConnectToWS(t, table.write, w, "ws")
conn := helpers.ShouldEventuallyReceive(t, c, 100*time.Millisecond).(*wsConn)
defer conn.Close()
a := conn.RemoteAddr().String()
Expand All @@ -166,7 +185,7 @@ func TestWSConnSetDeadline(t *testing.T) {
c := w.GetConnChan()
defer w.Stop()
go w.ListenAndServe()
mustConnectToWS(t, table.write, w)
mustConnectToWS(t, table.write, w, "ws")
conn := helpers.ShouldEventuallyReceive(t, c, 100*time.Millisecond).(*wsConn)
defer conn.Close()
conn.SetDeadline(time.Now().Add(5 * time.Millisecond))
Expand Down

0 comments on commit 1825b59

Please sign in to comment.