-
Notifications
You must be signed in to change notification settings - Fork 161
/
jprqc.go
110 lines (94 loc) · 2.84 KB
/
jprqc.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package main
import (
"encoding/binary"
"fmt"
"log"
"net"
"strings"
"github.com/azimjohn/jprq/cli/debugger"
"github.com/azimjohn/jprq/server/events"
"github.com/azimjohn/jprq/server/tunnel"
)
type jprqClient struct {
config Config
protocol string
subdomain string
cname string
localServer string
remoteServer string
publicServer string
httpDebugger debugger.Debugger
}
func (j *jprqClient) Start(port int, debug bool) {
eventCon, err := net.Dial("tcp", j.config.Remote.Events)
if err != nil {
log.Fatalf("failed to connect to event server: %s\n", err)
}
defer eventCon.Close()
request := events.Event[events.TunnelRequested]{
Data: &events.TunnelRequested{
Protocol: j.protocol,
Subdomain: j.subdomain,
CanonName: j.cname,
AuthToken: j.config.Local.AuthToken,
CliVersion: version,
},
}
if err := request.Write(eventCon); err != nil {
log.Fatalf("failed to send request: %s\n", err)
}
var t events.Event[events.TunnelOpened]
if err := t.Read(eventCon); err != nil {
log.Fatalf("failed to receive tunnel info: %s\n", err)
}
if t.Data.ErrorMessage != "" {
log.Fatalf(t.Data.ErrorMessage)
}
j.localServer = fmt.Sprintf("localhost:%d", port)
j.remoteServer = fmt.Sprintf("jprq.%s:%d", j.config.Remote.Domain, t.Data.PrivateServer)
j.publicServer = fmt.Sprintf("%s:%d", t.Data.Hostname, t.Data.PublicServer)
if j.protocol == "http" {
j.publicServer = fmt.Sprintf("https://%s", t.Data.Hostname)
}
fmt.Printf("Status: \t Online \n")
fmt.Printf("Protocol: \t %s \n", strings.ToUpper(j.protocol))
fmt.Printf("Forwarded: \t %s -> %s \n", strings.TrimSuffix(j.publicServer, ":80"), j.localServer)
if j.protocol == "http" && debug {
j.httpDebugger = debugger.New()
if port, err := j.httpDebugger.Run(0); err == nil {
fmt.Printf("Http Debugger: \t http://127.0.0.1:%d \n", port)
}
}
var event events.Event[events.ConnectionReceived]
for {
if err := event.Read(eventCon); err != nil {
log.Fatalf("failed to receive connection-received event: %s\n", err)
}
go j.handleEvent(*event.Data)
}
}
func (j *jprqClient) handleEvent(event events.ConnectionReceived) {
localCon, err := net.Dial("tcp", j.localServer)
if err != nil {
log.Printf("failed to connect to local server: %s\n", err)
return
}
defer localCon.Close()
remoteCon, err := net.Dial("tcp", j.remoteServer)
if err != nil {
log.Printf("failed to connect to remote server: %s\n", err)
return
}
defer remoteCon.Close()
buffer := make([]byte, 2)
binary.LittleEndian.PutUint16(buffer, event.ClientPort)
remoteCon.Write(buffer)
if j.httpDebugger == nil {
go tunnel.Bind(localCon, remoteCon, nil)
tunnel.Bind(remoteCon, localCon, nil)
return
}
debugCon := j.httpDebugger.Connection(event.ClientPort)
go tunnel.Bind(localCon, remoteCon, debugCon.Response())
tunnel.Bind(remoteCon, localCon, debugCon.Request())
}