@@ -22,6 +22,7 @@ import (
2222 "io"
2323 "log"
2424 "net"
25+ "net/netip"
2526 "os"
2627 "os/signal"
2728 "regexp"
@@ -48,10 +49,10 @@ import (
4849)
4950
5051var (
51- port = flag .Int ("port" , 0 , "bind port (all addresses)" )
52+ portArg = flag .String ("port" , "0" , "bind port (all addresses)" )
5253 forward = flag .String ("forward" , "" , "forwarding target" )
53- client = flag .Bool ("client" , false , "use netstack for listen " )
54- server = flag .Bool ("server" , false , "use netstack for dial " )
54+ client = flag .Bool ("client" , false , "use netstack for dial " )
55+ server = flag .Bool ("server" , false , "use netstack for listen " )
5556
5657 // Netstack-specific options.
5758 mtu = flag .Int ("mtu" , 1280 , "mtu for network stack" )
@@ -78,22 +79,17 @@ var (
7879)
7980
8081type impl interface {
81- dial (address string ) (net.Conn , error )
82- listen (port int ) (net.Listener , error )
82+ listen (port uint16 ) (net.Listener , error )
8383 printStats ()
8484}
8585
8686type netImpl struct {}
8787
88- func (netImpl ) dial (address string ) (net.Conn , error ) {
89- return net .Dial ("tcp" , address )
90- }
91-
92- func (netImpl ) listen (port int ) (net.Listener , error ) {
88+ func (* netImpl ) listen (port uint16 ) (net.Listener , error ) {
9389 return net .Listen ("tcp" , fmt .Sprintf (":%d" , port ))
9490}
9591
96- func (netImpl ) printStats () {
92+ func (* netImpl ) printStats () {
9793}
9894
9995const (
@@ -159,7 +155,7 @@ func setupNetwork(ifaceName string, numChannels int) (fds []int, err error) {
159155 return nil , fmt .Errorf ("failed to find interface: %v" , ifaceName )
160156}
161157
162- func newNetstackImpl (mode , probeFileName string ) (impl , func () error , error ) {
158+ func newNetstackImpl (mode , probeFileName string ) (* netstackImpl , func () error , error ) {
163159 // Parse details.
164160 var parsedAddr tcpip.Address
165161 if * useIpv6 {
@@ -327,30 +323,18 @@ func newNetstackImpl(mode, probeFileName string) (impl, func() error, error) {
327323 }
328324 }
329325
330- return netstackImpl {
326+ return & netstackImpl {
331327 s : s ,
332328 addr : parsedAddr ,
333329 mode : mode ,
334330 }, probeFile .Close , nil
335331}
336332
337- func (n netstackImpl ) dial (address string ) (net.Conn , error ) {
338- host , port , err := net .SplitHostPort (address )
339- if err != nil {
340- return nil , err
341- }
342- if host == "" {
343- // A host must be provided for the dial.
344- return nil , fmt .Errorf ("no host provided" )
345- }
346- portNumber , err := strconv .Atoi (port )
347- if err != nil {
348- return nil , err
349- }
333+ func (n * netstackImpl ) dial (remote netip.AddrPort ) (net.Conn , error ) {
350334 addr := tcpip.FullAddress {
351335 NIC : nicID ,
352- Addr : tcpip .AddrFromSlice ( net . ParseIP ( host )),
353- Port : uint16 ( portNumber ),
336+ Addr : tcpip .AddrFrom16 ( remote . Addr (). As16 ( )),
337+ Port : remote . Port ( ),
354338 }
355339 proto := ipv4 .ProtocolNumber
356340 if * useIpv6 {
@@ -363,10 +347,10 @@ func (n netstackImpl) dial(address string) (net.Conn, error) {
363347 return conn , nil
364348}
365349
366- func (n netstackImpl ) listen (port int ) (net.Listener , error ) {
350+ func (n * netstackImpl ) listen (port uint16 ) (net.Listener , error ) {
367351 addr := tcpip.FullAddress {
368352 NIC : nicID ,
369- Port : uint16 ( port ) ,
353+ Port : port ,
370354 }
371355 proto := ipv4 .ProtocolNumber
372356 if * useIpv6 {
@@ -381,20 +365,34 @@ func (n netstackImpl) listen(port int) (net.Listener, error) {
381365
382366var zeroFieldsRegexp = regexp .MustCompile (`\s*[a-zA-Z0-9]*:0` )
383367
384- func (n netstackImpl ) printStats () {
368+ func (n * netstackImpl ) printStats () {
385369 // Don't show zero fields.
386370 stats := zeroFieldsRegexp .ReplaceAllString (fmt .Sprintf ("%+v" , n .s .Stats ()), "" )
387371 log .Printf ("netstack %s Stats: %+v\n " , n .mode , stats )
388372}
389373
390374func main () {
391375 flag .Parse ()
392- if * port == 0 {
376+ port , err := strconv .ParseUint (* portArg , 0 , 16 )
377+ if err != nil {
378+ log .Fatalf ("invalid listen port: %v" , err )
379+ }
380+ if port == 0 {
393381 log .Fatalf ("no port provided" )
394382 }
395383 if * forward == "" {
396384 log .Fatalf ("no forward provided" )
397385 }
386+ var target netip.AddrPort
387+ if * client {
388+ target , err = netip .ParseAddrPort (* forward )
389+ if err != nil {
390+ log .Fatalf ("invalid forwarding target: %v" , err )
391+ }
392+ if target .Addr ().Zone () != "" {
393+ log .Fatalf ("netstack forwarding uses -iface; omit the zone in %q" , * forward )
394+ }
395+ }
398396 if * cpuprofile != "" {
399397 f , err := os .Create (* cpuprofile )
400398 if err != nil {
@@ -440,36 +438,31 @@ func main() {
440438 runtime .SetBlockProfileRate (1000 )
441439 }
442440
443- var (
444- in impl
445- out impl
446- err error
447- cleanup func () error
448- )
441+ var in impl = & netImpl {}
449442 if * server {
450- in , cleanup , err = newNetstackImpl ("server" , * serverTCPProbeFile )
443+ n , cleanup , err := newNetstackImpl ("server" , * serverTCPProbeFile )
444+ if err != nil {
445+ log .Fatalf ("netstack error: %v" , err )
446+ }
451447 defer cleanup ()
452-
453- } else {
454- in = netImpl {}
455- }
456- if err != nil {
457- log .Fatalf ("netstack error: %v" , err )
448+ in = n
458449 }
450+ var out impl = & netImpl {}
451+ dial := func () (net.Conn , error ) { return net .Dial ("tcp" , * forward ) }
459452 if * client {
460- out , cleanup , err = newNetstackImpl ("client" , * clientTCPProbeFile )
453+ n , cleanup , err := newNetstackImpl ("client" , * clientTCPProbeFile )
454+ if err != nil {
455+ log .Fatalf ("netstack error: %v" , err )
456+ }
461457 defer cleanup ()
462- } else {
463- out = netImpl {}
464- }
465- if err != nil {
466- log .Fatalf ("netstack error: %v" , err )
458+ out = n
459+ dial = func () (net.Conn , error ) { return n .dial (target ) }
467460 }
468461
469462 // Dial forward before binding.
470463 var next net.Conn
471464 for {
472- next , err = out . dial (* forward )
465+ next , err = dial ()
473466 if err == nil {
474467 break
475468 }
@@ -478,7 +471,7 @@ func main() {
478471 }
479472
480473 // Bind once to the server socket.
481- listener , err := in .listen (* port )
474+ listener , err := in .listen (uint16 ( port ) )
482475 if err != nil {
483476 // Should not happen, everything must be bound by this time
484477 // this proxy is started.
@@ -523,7 +516,7 @@ func main() {
523516
524517 for {
525518 // Dial again.
526- next , err = out . dial (* forward )
519+ next , err = dial ()
527520 if err == nil {
528521 break
529522 }
0 commit comments