-
Notifications
You must be signed in to change notification settings - Fork 77
/
rabbit.go
100 lines (90 loc) · 2.57 KB
/
rabbit.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
package main
import (
"flag"
"github.com/ihciah/rabbit-tcp/client"
"github.com/ihciah/rabbit-tcp/logger"
"github.com/ihciah/rabbit-tcp/server"
"github.com/ihciah/rabbit-tcp/tunnel"
"log"
"strings"
)
var Version = "No version information"
const (
ClientMode = iota
ServerMode
DefaultPassword = "PASSWORD"
)
func parseFlags() (pass bool, mode int, password string, addr string, listen string, dest string, tunnelN int, verbose int) {
var modeString string
var printVersion bool
flag.StringVar(&modeString, "mode", "c", "running mode(s or c)")
flag.StringVar(&password, "password", DefaultPassword, "password")
flag.StringVar(&addr, "rabbit-addr", ":443", "listen(server mode) or remote(client mode) address used by rabbit-tcp")
flag.StringVar(&listen, "listen", "", "[Client Only] listen address, eg: 127.0.0.1:2333")
flag.StringVar(&dest, "dest", "", "[Client Only] destination address, eg: shadowsocks server address")
flag.IntVar(&tunnelN, "tunnelN", 4, "[Client Only] number of tunnels to use in rabbit-tcp")
flag.IntVar(&verbose, "verbose", 2, "verbose level(0~5)")
flag.BoolVar(&printVersion, "version", false, "show version")
flag.Parse()
pass = true
// version
if printVersion {
log.Println("Rabbit TCP (https://github.com/ihciah/rabbit-tcp/)")
log.Printf("Version: %s.\n", Version)
pass = false
return
}
// mode
modeString = strings.ToLower(modeString)
if modeString == "c" || modeString == "client" {
mode = ClientMode
} else if modeString == "s" || modeString == "server" {
mode = ServerMode
} else {
log.Printf("Unsupported mode %s.\n", modeString)
pass = false
return
}
// password
if password == "" {
log.Println("Password must be specified.")
pass = false
return
}
if password == DefaultPassword {
log.Println("Password must be changed instead of default password.")
pass = false
return
}
// listen, dest, tunnelN
if mode == ClientMode {
if listen == "" {
log.Println("Listen address must be specified in client mode.")
pass = false
}
if dest == "" {
log.Println("Destination address must be specified in client mode.")
pass = false
}
if tunnelN == 0 {
log.Println("Tunnel number must be positive.")
pass = false
}
}
return
}
func main() {
pass, mode, password, addr, listen, dest, tunnelN, verbose := parseFlags()
if !pass {
return
}
cipher, _ := tunnel.NewAEADCipher("CHACHA20-IETF-POLY1305", nil, password)
logger.LEVEL = verbose
if mode == ClientMode {
c := client.NewClient(tunnelN, addr, cipher)
c.ServeForward(listen, dest)
} else {
s := server.NewServer(cipher)
s.Serve(addr)
}
}