1
1
package main
2
2
3
3
import (
4
+ "bufio"
4
5
"flag"
5
6
"fmt"
6
7
"io"
@@ -18,37 +19,48 @@ import (
18
19
19
20
func printUsage () {
20
21
fmt .Println ("netcat [flags] host-address port" )
22
+ fmt .Println ("netcat [flags] -l port" )
21
23
fmt .Println ("The host address is specified as ISD-AS,[IP Address]" )
22
24
fmt .Println ("Example SCION address: 17-ffaa:1:bfd,[127.0.0.1]:42002" )
23
25
fmt .Println ("Available flags:" )
24
26
fmt .Println (" -h: Show help" )
25
27
fmt .Println (" -local: Local SCION address (default localhost)" )
26
- fmt .Println (" -b: Send an extra byte before sending the actual data" )
28
+ fmt .Println (" -b: Send or expect an extra (throw-away) byte before the actual data" )
29
+ fmt .Println (" -tlsKey: TLS key path, only needed when listening (default: ./key.pem)" )
30
+ fmt .Println (" -tlsCertificate: TLS certificate path, only needed when listening (default: ./certificate.pem)" )
27
31
}
28
32
29
33
func main () {
30
34
log .SetupLogConsole ("debug" )
31
35
log .Debug ("Launching netcat" )
32
36
33
37
var (
34
- remoteAddressString string
35
- port uint16
36
- localAddrString string
37
- extraByte bool
38
+ remoteAddressString string
39
+ port uint16
40
+ localAddrString string
41
+
42
+ quicTLSKeyPath string
43
+ quicTLSCertificatePath string
44
+
45
+ extraByte bool
46
+ listen bool
38
47
)
39
48
flag .Usage = printUsage
40
49
flag .StringVar (& remoteAddressString , "local" , "" , "Local address string" )
41
- flag .BoolVar (& extraByte , "b" , false , "Send extra byte" )
50
+ flag .StringVar (& quicTLSKeyPath , "tlsKey" , "./key.pem" , "TLS key path" )
51
+ flag .StringVar (& quicTLSCertificatePath , "tlsCert" , "./certificate.pem" , "TLS certificate path" )
52
+ flag .BoolVar (& extraByte , "b" , false , "Expect extra byte" )
53
+ flag .BoolVar (& listen , "l" , false , "Listen mode" )
42
54
flag .Parse ()
43
55
44
56
tail := flag .Args ()
45
- if len (tail ) != 2 {
57
+ if ! ( len (tail ) == 1 && listen ) && ! ( len ( tail ) == 2 && ! listen ) {
46
58
printUsage ()
47
- golog .Panicf ("Number of arguments is not two ! Arguments: %v" , tail )
59
+ golog .Panicf ("Incorrect number of arguments! Arguments: %v" , tail )
48
60
}
49
61
50
62
remoteAddressString = tail [0 ]
51
- port64 , err := strconv .ParseUint (tail [1 ], 10 , 16 )
63
+ port64 , err := strconv .ParseUint (tail [len ( tail ) - 1 ], 10 , 16 )
52
64
if err != nil {
53
65
printUsage ()
54
66
golog .Panicf ("Can't parse port string %v: %v" , port64 , err )
@@ -73,30 +85,25 @@ func main() {
73
85
golog .Panicf ("Error initializing SCION connection: %v" , err )
74
86
}
75
87
76
- remoteAddr , err := snet .AddrFromString (fmt .Sprintf ("%s:%v" , remoteAddressString , port ))
77
- if err != nil {
78
- golog .Panicf ("Can't parse remote address %s: %v" , remoteAddressString )
79
- }
80
-
81
- sess , err := squic .DialSCION (nil , localAddr , remoteAddr , & quic.Config {KeepAlive : true })
82
- if err != nil {
83
- golog .Panicf ("Can't dial remote address %s: %v" , remoteAddressString , err )
84
- }
85
-
86
- stream , err := sess .OpenStreamSync ()
87
- if err != nil {
88
- golog .Panicf ("Can't open stream: %v" , err )
89
- }
88
+ var (
89
+ sess quic.Session
90
+ stream quic.Stream
91
+ )
90
92
91
- log .Debug ("Connected!" )
93
+ if listen {
94
+ err := squic .Init (quicTLSKeyPath , quicTLSCertificatePath )
95
+ if err != nil {
96
+ golog .Panicf ("Error initializing squic: %v" , err )
97
+ }
92
98
93
- if extraByte {
94
- _ , err := stream .Write ([]byte {71 })
99
+ sess , stream = doListen (localAddr , extraByte )
100
+ } else {
101
+ remoteAddr , err := snet .AddrFromString (fmt .Sprintf ("%s:%v" , remoteAddressString , port ))
95
102
if err != nil {
96
- golog .Panicf ("Error writing extra byte : %v" , err )
103
+ golog .Panicf ("Can't parse remote address %s : %v" , remoteAddressString )
97
104
}
98
105
99
- log . Debug ( "Sent extra byte!" )
106
+ sess , stream = doDial ( localAddr , remoteAddr , extraByte )
100
107
}
101
108
102
109
close := func () {
@@ -117,6 +124,56 @@ func main() {
117
124
}()
118
125
io .Copy (stream , os .Stdin )
119
126
once .Do (close )
127
+ }
128
+
129
+ func doListen (localAddr * snet.Addr , extraByte bool ) (quic.Session , quic.Stream ) {
130
+ listener , err := squic .ListenSCION (nil , localAddr , & quic.Config {KeepAlive : true })
131
+ if err != nil {
132
+ golog .Panicf ("Can't listen on address %v: %v" , localAddr , err )
133
+ }
134
+
135
+ sess , err := listener .Accept ()
136
+ if err != nil {
137
+ golog .Panicf ("Can't accept listener: %v" , err )
138
+ }
139
+
140
+ stream , err := sess .AcceptStream ()
141
+ if err != nil {
142
+ golog .Panicf ("Can't accept stream: %v" , err )
143
+ }
144
+
145
+ log .Debug ("Connected!" )
146
+
147
+ if extraByte {
148
+ (* bufio .NewReader (stream )).ReadByte ()
149
+
150
+ log .Debug ("Received extra byte!" )
151
+ }
152
+
153
+ return sess , stream
154
+ }
155
+
156
+ func doDial (localAddr , remoteAddr * snet.Addr , extraByte bool ) (quic.Session , quic.Stream ) {
157
+ sess , err := squic .DialSCION (nil , localAddr , remoteAddr , & quic.Config {KeepAlive : true })
158
+ if err != nil {
159
+ golog .Panicf ("Can't dial remote address %v: %v" , remoteAddr , err )
160
+ }
161
+
162
+ stream , err := sess .OpenStreamSync ()
163
+ if err != nil {
164
+ golog .Panicf ("Can't open stream: %v" , err )
165
+ }
166
+
167
+ log .Debug ("Connected!" )
168
+
169
+ if extraByte {
170
+ _ , err := stream .Write ([]byte {71 })
171
+ if err != nil {
172
+ golog .Panicf ("Error writing extra byte: %v" , err )
173
+ }
174
+
175
+ log .Debug ("Sent extra byte!" )
176
+ }
120
177
121
- log . Debug ( "Exiting snetcat..." )
178
+ return sess , stream
122
179
}
0 commit comments