squash refactor

This commit is contained in:
AJ ONeal 2020-05-01 01:06:14 -06:00
parent e57917a252
commit 7d6437f4c5
30 changed files with 94 additions and 349 deletions

View File

@ -12,7 +12,6 @@ import (
"os" "os"
"strings" "strings"
telebit "git.coolaj86.com/coolaj86/go-telebitd"
"git.coolaj86.com/coolaj86/go-telebitd/log" "git.coolaj86.com/coolaj86/go-telebitd/log"
"git.coolaj86.com/coolaj86/go-telebitd/relay" "git.coolaj86.com/coolaj86/go-telebitd/relay"
"git.coolaj86.com/coolaj86/go-telebitd/relay/api" "git.coolaj86.com/coolaj86/go-telebitd/relay/api"
@ -46,7 +45,7 @@ var (
connectionTable *api.Table connectionTable *api.Table
secretKey string secretKey string
wssHostName = "localhost.rootprojects.org" wssHostName = "localhost.rootprojects.org"
adminHostName = telebit.InvalidAdminDomain adminHostName string
idle int idle int
dwell int dwell int
cancelcheck int cancelcheck int

View File

@ -1,124 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Websock VPN Instrumentation</title>
</head>
<body ng-app="vpnAdmin" ng-controller="vpnInstrumentationController">
<div class="panel panel-default panel-primary">
<div class="panel-heading">VPN Instrumentation</div>
<div class="panel-body">
<div class="panel panel-default panel-info">
<div class="panel-heading">Control Plane</div>
<div class="panel-body">
<div class="row">
<!-- Auth -->
<div class="col-lg-6">
<div class="input-group">
<span class="input-group-btn">
<button class="btn btn-default" type="button" ng-click="startWebSocket()">
Start WebSocket
</button>
</span>
<button
class="btn btn-default"
type="button"
ng-class="conn == false && 'btn-danger' || 'btn-success'"
>
{[{ conn == false && 'False' || 'True' }]}
</button>
</div>
</div>
</div>
<br />
<div class="row">
<div class="col-lg-6">
<div class="input-group">
<span class="input-group-btn">
<button class="btn btn-default" type="button">Auth</button>
</span>
<input type="text" class="form-control" placeholder="Enter auth data here" />
</div>
</div>
</div>
</div>
</div>
<div class="panel panel-default panel-info">
<div class="panel-heading">Data</div>
<div class="panel-body">
<p ng-repeat="text in log_elements">{[{text}]}</p>
</div>
</div>
</div>
</div>
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.min.js"></script>
<link
rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
crossorigin="anonymous"
/>
<link
rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css"
integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp"
crossorigin="anonymous"
/>
<script
src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"
integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
crossorigin="anonymous"
></script>
<script type="text/javascript">
console.log("startup");
var vpnAdmin = angular.module("vpnAdmin", []);
vpnAdmin.config(function ($interpolateProvider) {
console.log("vpnTest Config");
$interpolateProvider.startSymbol("{[{");
$interpolateProvider.endSymbol("}]}");
});
vpnAdmin.controller("vpnInstrumentationController", function ($scope) {
console.log("vpnInstrumentationController startup");
$scope.log_elements = [];
$scope.auth_key = "";
$scope.conn = false;
$scope.webSocketStatus = function () {
if ($scope.conn == false) {
return "";
}
};
$scope.startWebSocket = function () {
console.log("Start webSocket {{$}}");
if (window["WebSocket"]) {
$scope.conn = new WebSocket("wss://{{$}}/ws/admin");
$scope.append_log("Websocket opened");
$scope.conn.onclose = function (evt) {
$scope.append_log("Connection closed.");
};
$scope.conn.onmessage = function (evt) {
$scope.append_log(evt.data);
};
} else {
appendLog($("<div><b>Your browser does not support WebSockets.</b></div>"));
}
};
$scope.auth_click = function () {
$scope.append_log($scope.auth_key);
};
$scope.append_log = function (txt) {
$scope.log_elements.push(txt);
};
});
</script>
</html>

View File

@ -1,151 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Websock VPN Test Client</title>
</head>
<body ng-app="vpnTest" ng-controller="vpnTestController">
<div class="panel panel-default panel-primary">
<div class="panel-heading">WebSocket Client Test</div>
<div class="panel-body">
<div class="panel panel-default panel-info">
<div class="panel-heading">Control Plane</div>
<div class="panel-body">
<div class="row">
<!-- Auth -->
<div class="col-lg-6">
<div class="input-group">
<span class="input-group-btn">
<button class="btn btn-default" type="button" ng-click="startWebSocket()">
Start WebSocket
</button>
</span>
<button
class="btn btn-default"
type="button"
ng-class="conn == false && 'btn-danger' || 'btn-success'"
>
{[{ conn == false && 'False' || 'True' }]}
</button>
</div>
</div>
</div>
<br />
<div class="row">
<div class="col-lg-6">
<div class="input-group">
<span class="input-group-btn">
<button class="btn btn-default" type="button">Auth</button>
</span>
<input type="text" class="form-control" placeholder="Enter auth data here" />
</div>
</div>
</div>
<br />
<div class="row">
<div class="col-lg-6">
<div class="input-group">
<span class="input-group-btn">
<button class="btn btn-default" ng-click="send_click()" type="button">
Send
</button>
</span>
<input
ng-model="send_data"
type="text"
class="form-control"
placeholder="Enter send data here"
/>
</div>
</div>
</div>
</div>
</div>
<div class="panel panel-default panel-danger">
<div class="panel-heading">Messages</div>
<div class="panel-body">
<p ng-repeat="text in log_elements">{[{text}]}</p>
</div>
</div>
</div>
</div>
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.min.js"></script>
<link
rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
crossorigin="anonymous"
/>
<link
rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css"
integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp"
crossorigin="anonymous"
/>
<script
src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"
integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
crossorigin="anonymous"
></script>
<script type="text/javascript">
console.log("startup");
var vpnTest = angular.module("vpnTest", []);
vpnTest.config(function ($interpolateProvider) {
console.log("vpnTest Config");
$interpolateProvider.startSymbol("{[{");
$interpolateProvider.endSymbol("}]}");
});
vpnTest.controller("vpnTestController", function ($scope) {
console.log("vpnTestController startup");
$scope.log_elements = [];
$scope.auth_key = "";
$scope.conn = false;
$scope.send_data = "";
$scope.webSocketStatus = function () {
if ($scope.conn == false) {
return "";
}
};
$scope.startWebSocket = function () {
console.log("Start webSocket {{$}}");
if (window["WebSocket"]) {
$scope.conn = new WebSocket("wss://{{$}}/ws/client");
$scope.append_log("Websocket opened");
$scope.conn.onclose = function (evt) {
$scope.append_log("Connection closed.");
};
$scope.conn.onmessage = function (evt) {
console.log(evt.data);
$scope.append_log(evt.data);
};
} else {
appendLog($("<div><b>Your browser does not support WebSockets.</b></div>"));
}
};
$scope.auth_click = function () {
$scope.append_log($scope.auth_key);
};
$scope.send_click = function () {
console.log("send_click");
$scope.conn.send($scope.send_data);
};
$scope.append_log = function (txt) {
$scope.log_elements.push(txt);
};
});
</script>
</html>

View File

@ -8,7 +8,6 @@ import (
"strconv" "strconv"
"strings" "strings"
telebit "git.coolaj86.com/coolaj86/go-telebitd"
"git.coolaj86.com/coolaj86/go-telebitd/relay/api" "git.coolaj86.com/coolaj86/go-telebitd/relay/api"
"git.coolaj86.com/coolaj86/go-telebitd/relay/mplexy" "git.coolaj86.com/coolaj86/go-telebitd/relay/mplexy"
@ -48,13 +47,23 @@ func ListenAndServe(mx *mplexy.MPlexy, adminListener net.Listener) error {
switch url := r.URL.Path; url { switch url := r.URL.Path; url {
case "/": case "/":
// check to see if we are using the administrative Host var hostname string
if strings.Contains(r.Host, telebit.InvalidAdminDomain) { host := strings.Split(r.Host, ":")
http.Redirect(w, r, "/admin", 301) if len(host) > 0 {
serverStatus.AdminStats.IncResponses() hostname = host[0]
} }
// check to see if we are using the administrative Host
if hostname == mplexy.InvalidAdminDomain {
http.Redirect(w, r, "/admin", 301)
serverStatus.AdminStats.IncResponses()
return
}
if hostname == mx.AdminDomain() {
http.Redirect(w, r, "/admin", 301)
serverStatus.AdminStats.IncResponses()
return
}
default: default:
http.Error(w, "Not Found", 404) http.Error(w, "Not Found", 404)
} }

View File

@ -4,7 +4,7 @@ import (
"context" "context"
"time" "time"
"git.coolaj86.com/coolaj86/go-telebitd/tunnel" "git.coolaj86.com/coolaj86/go-telebitd/relay/tunnel"
) )
//Status -- //Status --

View File

@ -13,11 +13,10 @@ import (
"strings" "strings"
"time" "time"
telebit "git.coolaj86.com/coolaj86/go-telebitd"
"git.coolaj86.com/coolaj86/go-telebitd/packer" "git.coolaj86.com/coolaj86/go-telebitd/packer"
"git.coolaj86.com/coolaj86/go-telebitd/relay/api" "git.coolaj86.com/coolaj86/go-telebitd/relay/api"
"git.coolaj86.com/coolaj86/go-telebitd/relay/tunnel"
"git.coolaj86.com/coolaj86/go-telebitd/sni" "git.coolaj86.com/coolaj86/go-telebitd/sni"
"git.coolaj86.com/coolaj86/go-telebitd/tunnel"
) )
type contextKey string type contextKey string
@ -29,7 +28,6 @@ const (
ctxListenerRegistration contextKey = "listenerRegistration" ctxListenerRegistration contextKey = "listenerRegistration"
ctxConnectionTrack contextKey = "connectionTrack" ctxConnectionTrack contextKey = "connectionTrack"
ctxWssHostName contextKey = "wsshostname" ctxWssHostName contextKey = "wsshostname"
ctxAdminHostName contextKey = "adminHostName"
ctxCancelCheck contextKey = "cancelcheck" ctxCancelCheck contextKey = "cancelcheck"
ctxLoadbalanceDefaultMethod contextKey = "lbdefaultmethod" ctxLoadbalanceDefaultMethod contextKey = "lbdefaultmethod"
//ctxConnectionTable contextKey = "connectionTable" //ctxConnectionTable contextKey = "connectionTable"
@ -55,19 +53,19 @@ const (
// - if TLS, consume connection with TLS certbundle, pass to request identifier // - if TLS, consume connection with TLS certbundle, pass to request identifier
// - else, just pass to the request identififer // - else, just pass to the request identififer
func (mx *MPlexy) multiListenAndServe(ctx context.Context, listenerRegistration *ListenerRegistration) { func (mx *MPlexy) multiListenAndServe(ctx context.Context, listenerRegistration *ListenerRegistration) {
Loginfo.Println(":" + string(listenerRegistration.port)) loginfo.Println(":" + string(listenerRegistration.port))
cancelCheck := ctx.Value(ctxCancelCheck).(int) cancelCheck := ctx.Value(ctxCancelCheck).(int)
listenAddr, err := net.ResolveTCPAddr("tcp", ":"+strconv.Itoa(listenerRegistration.port)) listenAddr, err := net.ResolveTCPAddr("tcp", ":"+strconv.Itoa(listenerRegistration.port))
if nil != err { if nil != err {
Loginfo.Println(err) loginfo.Println(err)
return return
} }
ln, err := net.ListenTCP("tcp", listenAddr) ln, err := net.ListenTCP("tcp", listenAddr)
if err != nil { if err != nil {
Loginfo.Println("unable to bind", err) loginfo.Println("unable to bind", err)
listenerRegistration.status = listenerFault listenerRegistration.status = listenerFault
listenerRegistration.err = err listenerRegistration.err = err
listenerRegistration.commCh <- listenerRegistration listenerRegistration.commCh <- listenerRegistration
@ -80,7 +78,7 @@ func (mx *MPlexy) multiListenAndServe(ctx context.Context, listenerRegistration
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():
Loginfo.Println("Cancel signal hit") loginfo.Println("Cancel signal hit")
return return
default: default:
ln.SetDeadline(time.Now().Add(time.Duration(cancelCheck) * time.Second)) ln.SetDeadline(time.Now().Add(time.Duration(cancelCheck) * time.Second))
@ -91,7 +89,7 @@ func (mx *MPlexy) multiListenAndServe(ctx context.Context, listenerRegistration
if opErr, ok := err.(*net.OpError); ok && opErr.Timeout() { if opErr, ok := err.(*net.OpError); ok && opErr.Timeout() {
continue continue
} }
Loginfo.Println(err) loginfo.Println(err)
return return
} }
@ -114,10 +112,10 @@ func (mx *MPlexy) accept(ctx context.Context, wConn *tunnel.WedgeConn) {
encryptMode := encryptNone encryptMode := encryptNone
Loginfo.Println("new conn", wConn, wConn.LocalAddr().String(), wConn.RemoteAddr().String()) loginfo.Println("new conn", wConn, wConn.LocalAddr().String(), wConn.RemoteAddr().String())
peek, err := wConn.Peek(peekCnt) peek, err := wConn.Peek(peekCnt)
if err != nil { if err != nil {
Loginfo.Println("error while peeking") loginfo.Println("error while peeking")
wConn.Close() wConn.Close()
return return
} }
@ -131,7 +129,7 @@ func (mx *MPlexy) accept(ctx context.Context, wConn *tunnel.WedgeConn) {
} else if bytes.Contains(peek[0:3], []byte{0x16, 0x03, 0x01}) { } else if bytes.Contains(peek[0:3], []byte{0x16, 0x03, 0x01}) {
encryptMode = encryptTLS10 encryptMode = encryptTLS10
Loginfo.Println("TLS10") loginfo.Println("TLS10")
} else if bytes.Contains(peek[0:3], []byte{0x16, 0x03, 0x02}) { } else if bytes.Contains(peek[0:3], []byte{0x16, 0x03, 0x02}) {
encryptMode = encryptTLS11 encryptMode = encryptTLS11
@ -145,19 +143,19 @@ func (mx *MPlexy) accept(ctx context.Context, wConn *tunnel.WedgeConn) {
} }
if encryptMode == encryptSSLV2 { if encryptMode == encryptSSLV2 {
Loginfo.Println("<= SSLv2 is not accepted") loginfo.Println("<= SSLv2 is not accepted")
wConn.Close() wConn.Close()
return return
} }
if encryptMode == encryptNone { if encryptMode == encryptNone {
Loginfo.Println("Handle Unencrypted") loginfo.Println("Handle Unencrypted")
mx.acceptPlainStream(ctx, wConn, false) mx.acceptPlainStream(ctx, wConn, false)
return return
} }
Loginfo.Println("Handle Encryption") loginfo.Println("Handle Encryption")
mx.acceptEncryptedStream(ctx, wConn) mx.acceptEncryptedStream(ctx, wConn)
} }
@ -166,21 +164,21 @@ func (mx *MPlexy) acceptEncryptedStream(ctx context.Context, wConn *tunnel.Wedge
peek, err := wConn.PeekAll() peek, err := wConn.PeekAll()
if err != nil { if err != nil {
Loginfo.Println("Bad socket: read error from", wConn.RemoteAddr(), err) loginfo.Println("Bad socket: read error from", wConn.RemoteAddr(), err)
Loginfo.Println(hex.Dump(peek[0:])) loginfo.Println(hex.Dump(peek[0:]))
wConn.Close() wConn.Close()
return return
} }
sniHostName, err := sni.GetHostname(peek) sniHostName, err := sni.GetHostname(peek)
if err != nil { if err != nil {
Loginfo.Println("Bad socket: no SNI from", wConn.RemoteAddr(), err) loginfo.Println("Bad socket: no SNI from", wConn.RemoteAddr(), err)
Loginfo.Println(err) loginfo.Println(err)
wConn.Close() wConn.Close()
return return
} }
Loginfo.Println("SNI:", sniHostName) loginfo.Println("SNI:", sniHostName)
if sniHostName == mx.wssHostName || sniHostName == mx.adminHostName { if sniHostName == mx.wssHostName || sniHostName == mx.adminHostName {
// The TLS should be terminated and handled internally // The TLS should be terminated and handled internally
@ -194,7 +192,7 @@ func (mx *MPlexy) acceptEncryptedStream(ctx context.Context, wConn *tunnel.Wedge
//oneConn := &oneConnListener{wConn} //oneConn := &oneConnListener{wConn}
// TLS remains intact and shall be routed downstream, wholesale // TLS remains intact and shall be routed downstream, wholesale
Loginfo.Println("processing non terminating traffic", mx.wssHostName, sniHostName) loginfo.Println("processing non terminating traffic", mx.wssHostName, sniHostName)
go mx.routeToTarget(ctx, wConn, sniHostName, "https") go mx.routeToTarget(ctx, wConn, sniHostName, "https")
} }
@ -207,13 +205,13 @@ func (mx *MPlexy) acceptEncryptedStream(ctx context.Context, wConn *tunnel.Wedge
// - else handle as raw http // - else handle as raw http
// - handle other? // - handle other?
func (mx *MPlexy) acceptPlainStream(ctx context.Context, wConn *tunnel.WedgeConn, encrypted bool) { func (mx *MPlexy) acceptPlainStream(ctx context.Context, wConn *tunnel.WedgeConn, encrypted bool) {
Loginfo.Println("Plain Conn", wConn.LocalAddr().String(), wConn.RemoteAddr().String()) loginfo.Println("Plain Conn", wConn.LocalAddr().String(), wConn.RemoteAddr().String())
// TODO couldn't reading everything be dangerous? Or is it limited to a single packet? // TODO couldn't reading everything be dangerous? Or is it limited to a single packet?
peek, err := wConn.PeekAll() peek, err := wConn.PeekAll()
if err != nil { if err != nil {
Loginfo.Println("error while peeking", err) loginfo.Println("error while peeking", err)
Loginfo.Println(hex.Dump(peek[0:])) loginfo.Println(hex.Dump(peek[0:]))
wConn.Close() wConn.Close()
return return
} }
@ -233,17 +231,23 @@ func (mx *MPlexy) acceptPlainStream(ctx context.Context, wConn *tunnel.WedgeConn
return return
} }
Loginfo.Println("identified HTTP") loginfo.Println("identified HTTP")
r, err := http.ReadRequest(bufio.NewReader(bytes.NewReader(peek))) r, err := http.ReadRequest(bufio.NewReader(bytes.NewReader(peek)))
if err != nil { if err != nil {
Loginfo.Println("identified as HTTP, failed request parsing", err) loginfo.Println("identified as HTTP, failed request parsing", err)
wConn.Close() wConn.Close()
return return
} }
if strings.Contains(r.Host, telebit.InvalidAdminDomain) { var hostname string
Loginfo.Println("admin") host := strings.Split(r.Host, ":")
if len(host) > 0 {
hostname = host[0]
}
if hostname == InvalidAdminDomain {
loginfo.Println("admin.invalid")
// TODO mx.Admin.CheckRemoteIP(conn) here // TODO mx.Admin.CheckRemoteIP(conn) here
// handle admin path // handle admin path
mx.AcceptAdminClient(wConn) mx.AcceptAdminClient(wConn)
@ -251,19 +255,24 @@ func (mx *MPlexy) acceptPlainStream(ctx context.Context, wConn *tunnel.WedgeConn
} }
// TODO add newtypes if hostname == mx.adminHostName {
// TODO check if this is a websocket loginfo.Println("admin")
_, err = mx.AuthorizeTarget(r) // TODO mx.Admin.CheckRemoteIP(conn) here
if err == nil { // handle admin path
Loginfo.Println("Valid WSS dected...sending to handler") mx.AcceptAdminClient(wConn)
return
}
if "Upgrade" == r.Header.Get("Connection") || "WebSocket" == r.Header.Get("Upgrade") {
loginfo.Println("WebSocket Upgrade is in order...")
mx.AcceptTargetServer(wConn) mx.AcceptTargetServer(wConn)
return return
} }
// TODO sniHostName is the key to the route, which could also be a port or hostname // TODO sniHostName is the key to the route, which could also be a port or hostname
//traffic not terminating on the rvpn do not decrypt //traffic not terminating on the rvpn do not decrypt
Loginfo.Println("processing non terminating traffic", mx.wssHostName, r.Host) loginfo.Println("processing non terminating traffic", mx.wssHostName, r.Host)
Loginfo.Println(hex.Dump(peek)) loginfo.Println(hex.Dump(peek))
if !encrypted { if !encrypted {
// TODO request and cache http resources as a feature?? // TODO request and cache http resources as a feature??
go mx.routeToTarget(ctx, wConn, r.Host, "http") go mx.routeToTarget(ctx, wConn, r.Host, "http")
@ -271,7 +280,7 @@ func (mx *MPlexy) acceptPlainStream(ctx context.Context, wConn *tunnel.WedgeConn
} }
// This is not presently possible // This is not presently possible
Loginfo.Println("impossible condition: local decryption of routable client", mx.wssHostName, r.Host) loginfo.Println("impossible condition: local decryption of routable client", mx.wssHostName, r.Host)
go mx.routeToTarget(ctx, wConn, r.Host, "https") go mx.routeToTarget(ctx, wConn, r.Host, "https")
} }
@ -293,7 +302,7 @@ func (mx *MPlexy) routeToTarget(ctx context.Context, extConn *tunnel.WedgeConn,
conn, ok := serverStatus.ConnectionTable.ConnByDomain(hostname) conn, ok := serverStatus.ConnectionTable.ConnByDomain(hostname)
if !ok { if !ok {
//matching connection can not be found based on ConnByDomain //matching connection can not be found based on ConnByDomain
Loginfo.Println("unable to match ", hostname, " to an existing connection") loginfo.Println("unable to match ", hostname, " to an existing connection")
//http.Error(, "Domain not supported", http.StatusBadRequest) //http.Error(, "Domain not supported", http.StatusBadRequest)
return return
} }
@ -302,15 +311,15 @@ func (mx *MPlexy) routeToTarget(ctx context.Context, extConn *tunnel.WedgeConn,
serverStatus.ExtConnectionRegister(track) serverStatus.ExtConnectionRegister(track)
remoteStr := extConn.RemoteAddr().String() remoteStr := extConn.RemoteAddr().String()
Loginfo.Println("Domain Accepted", hostname, remoteStr) loginfo.Println("Domain Accepted", hostname, remoteStr)
var header *packer.Header var header *packer.Header
if rAddr, rPort, err := net.SplitHostPort(remoteStr); err != nil { if rAddr, rPort, err := net.SplitHostPort(remoteStr); err != nil {
Loginfo.Println("unable to decode hostport", remoteStr, err) loginfo.Println("unable to decode hostport", remoteStr, err)
} else if port, err := strconv.Atoi(rPort); err != nil { } else if port, err := strconv.Atoi(rPort); err != nil {
Loginfo.Printf("unable to parse port string %q: %v\n", rPort, err) loginfo.Printf("unable to parse port string %q: %v\n", rPort, err)
} else if header, err = packer.NewHeader(rAddr, port, service); err != nil { } else if header, err = packer.NewHeader(rAddr, port, service); err != nil {
Loginfo.Println("unable to create packer header", err) loginfo.Println("unable to create packer header", err)
} }
if header == nil { if header == nil {
@ -320,17 +329,17 @@ func (mx *MPlexy) routeToTarget(ctx context.Context, extConn *tunnel.WedgeConn,
for { for {
buffer, err := extConn.PeekAll() buffer, err := extConn.PeekAll()
if err != nil { if err != nil {
Loginfo.Println("unable to peekAll", err) loginfo.Println("unable to peekAll", err)
return return
} }
Loginfo.Println("Before Packer", hex.Dump(buffer)) loginfo.Println("Before Packer", hex.Dump(buffer))
p := packer.NewPacker(header) p := packer.NewPacker(header)
p.Data.AppendBytes(buffer) p.Data.AppendBytes(buffer)
buf := p.PackV1() buf := p.PackV1()
//Loginfo.Println(hex.Dump(buf.Bytes())) //loginfo.Println(hex.Dump(buf.Bytes()))
//Bundle up the send request and dispatch //Bundle up the send request and dispatch
sendTrack := api.NewSendTrack(buf.Bytes(), hostname) sendTrack := api.NewSendTrack(buf.Bytes(), hostname)
@ -338,7 +347,7 @@ func (mx *MPlexy) routeToTarget(ctx context.Context, extConn *tunnel.WedgeConn,
cnt := len(buffer) cnt := len(buffer)
if _, err = extConn.Discard(cnt); err != nil { if _, err = extConn.Discard(cnt); err != nil {
Loginfo.Println("unable to discard", cnt, err) loginfo.Println("unable to discard", cnt, err)
return return
} }

View File

@ -10,7 +10,10 @@ import (
"git.coolaj86.com/coolaj86/go-telebitd/relay/api" "git.coolaj86.com/coolaj86/go-telebitd/relay/api"
) )
var Loginfo = log.Loginfo // InvalidAdminDomain is for bootstrapping the setup of a relay device
var InvalidAdminDomain = "admin.telebit.invalid"
var loginfo = log.Loginfo
var connectionID int64 = 0 var connectionID int64 = 0
//ListenerRegistrationStatus - post registration status //ListenerRegistrationStatus - post registration status
@ -112,13 +115,18 @@ func New(
return mx return mx
} }
// AdminDomain returns the Admin Domain as set on startup
func (mx *MPlexy) AdminDomain() string {
return mx.adminHostName
}
//Run -- Execute //Run -- Execute
// - execute the GenericLister // - execute the GenericLister
// - pass initial port, we'll announce that // - pass initial port, we'll announce that
func (mx *MPlexy) Run() error { func (mx *MPlexy) Run() error {
Loginfo.Println("ConnectionTable starting") loginfo.Println("ConnectionTable starting")
Loginfo.Println(mx.connectionTracking) loginfo.Println(mx.connectionTracking)
ctx := mx.ctx ctx := mx.ctx
@ -129,7 +137,6 @@ func (mx *MPlexy) Run() error {
ctx = context.WithValue(ctx, ctxConfig, mx.tlsConfig) ctx = context.WithValue(ctx, ctxConfig, mx.tlsConfig)
ctx = context.WithValue(ctx, ctxListenerRegistration, mx.register) ctx = context.WithValue(ctx, ctxListenerRegistration, mx.register)
ctx = context.WithValue(ctx, ctxWssHostName, mx.wssHostName) ctx = context.WithValue(ctx, ctxWssHostName, mx.wssHostName)
ctx = context.WithValue(ctx, ctxAdminHostName, mx.adminHostName)
ctx = context.WithValue(ctx, ctxCancelCheck, mx.cancelCheck) ctx = context.WithValue(ctx, ctxCancelCheck, mx.cancelCheck)
ctx = context.WithValue(ctx, ctxLoadbalanceDefaultMethod, mx.lbDefaultMethod) ctx = context.WithValue(ctx, ctxLoadbalanceDefaultMethod, mx.lbDefaultMethod)
ctx = context.WithValue(ctx, ctxServerStatus, mx.Status) ctx = context.WithValue(ctx, ctxServerStatus, mx.Status)
@ -138,29 +145,30 @@ func (mx *MPlexy) Run() error {
select { select {
case <-ctx.Done(): case <-ctx.Done():
Loginfo.Println("Cancel signal hit") loginfo.Println("Cancel signal hit")
return nil return nil
case registration := <-mx.register: case registration := <-mx.register:
Loginfo.Println("register fired", registration.port) loginfo.Println("register fired", registration.port)
// check to see if port is already running // check to see if port is already running
for listener := range mx.listeners { for listener := range mx.listeners {
if mx.listeners[listener] == registration.port { if mx.listeners[listener] == registration.port {
Loginfo.Println("listener already running", registration.port) loginfo.Println("listener already running", registration.port)
registration.status = listenerExists registration.status = listenerExists
registration.commCh <- registration registration.commCh <- registration
} }
} }
Loginfo.Println("listener starting up ", registration.port)
Loginfo.Println(ctx.Value(ctxConnectionTrack).(*api.Tracking)) loginfo.Println("listener starting up ", registration.port)
loginfo.Println("[track]", ctx.Value(ctxConnectionTrack).(*api.Tracking))
go mx.multiListenAndServe(ctx, registration) go mx.multiListenAndServe(ctx, registration)
status := <-registration.commCh status := <-registration.commCh
if status.status == listenerAdded { if status.status == listenerAdded {
mx.listeners[status.listener] = status.port mx.listeners[status.listener] = status.port
} else if status.status == listenerFault { } else if status.status == listenerFault {
Loginfo.Println("Unable to create a new listerer", registration.port) loginfo.Println("Unable to create a new listerer", registration.port)
} }
} }
} }
@ -168,6 +176,7 @@ func (mx *MPlexy) Run() error {
return nil return nil
} }
// Start calls go Run()
func (mx *MPlexy) Start() { func (mx *MPlexy) Start() {
go mx.Run() go mx.Run()
} }

View File

@ -10,7 +10,7 @@ import (
"git.coolaj86.com/coolaj86/go-telebitd/relay/admin" "git.coolaj86.com/coolaj86/go-telebitd/relay/admin"
"git.coolaj86.com/coolaj86/go-telebitd/relay/api" "git.coolaj86.com/coolaj86/go-telebitd/relay/api"
"git.coolaj86.com/coolaj86/go-telebitd/relay/mplexy" "git.coolaj86.com/coolaj86/go-telebitd/relay/mplexy"
"git.coolaj86.com/coolaj86/go-telebitd/tunnel" "git.coolaj86.com/coolaj86/go-telebitd/relay/tunnel"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
@ -78,7 +78,7 @@ func (r *Relay) ListenAndServe(port int) error {
return r.mx.Run() return r.mx.Run()
} }
func listenAndServeTargets(mx *mplexy.MPlexy, handler net.Listener) error { func listenAndServeTargets(mx *mplexy.MPlexy, listener net.Listener) error {
serverStatus := mx.Status serverStatus := mx.Status
router := mux.NewRouter().StrictSlash(true) router := mux.NewRouter().StrictSlash(true)
@ -121,5 +121,5 @@ func listenAndServeTargets(mx *mplexy.MPlexy, handler net.Listener) error {
Addr: ":80", Addr: ":80",
Handler: router, Handler: router,
} }
return s.Serve(handler) return s.Serve(listener)
} }

View File

@ -1,5 +1,7 @@
package sni package sni
// TODO this was probably copied from somewhere that deserves attribution
import ( import (
"errors" "errors"
) )

View File

@ -1,8 +0,0 @@
package telebit
// InvalidAdminDomain is a domain that can only be accessed by Domain Fronting
// (i.e. trixy clients sending fake headers), not browsers
var InvalidAdminDomain = "chilly-bobcat-15.telebit.io"
//var InvalidAdminDomain = "invalid.rootprojects.org"
//var InvalidAdminDomain = "rvpn.rootprojects.invalid"