use only local

This commit is contained in:
Zack Scholl 2020-10-21 10:23:12 -07:00
parent 1967ef57be
commit 3129b097af
2 changed files with 88 additions and 77 deletions

View File

@ -84,6 +84,7 @@ func Run() (err error) {
&cli.BoolFlag{Name: "stdout", Usage: "redirect file to stdout"}, &cli.BoolFlag{Name: "stdout", Usage: "redirect file to stdout"},
&cli.BoolFlag{Name: "no-compress", Usage: "disable compression"}, &cli.BoolFlag{Name: "no-compress", Usage: "disable compression"},
&cli.BoolFlag{Name: "ask", Usage: "make sure sender and recipient are prompted"}, &cli.BoolFlag{Name: "ask", Usage: "make sure sender and recipient are prompted"},
&cli.BoolFlag{Name: "local", Usage: "force to use only local connections"},
&cli.StringFlag{Name: "relay", Value: models.DEFAULT_RELAY, Usage: "address of the relay", EnvVars: []string{"CROC_RELAY"}}, &cli.StringFlag{Name: "relay", Value: models.DEFAULT_RELAY, Usage: "address of the relay", EnvVars: []string{"CROC_RELAY"}},
&cli.StringFlag{Name: "relay6", Value: models.DEFAULT_RELAY6, Usage: "ipv6 address of the relay", EnvVars: []string{"CROC_RELAY6"}}, &cli.StringFlag{Name: "relay6", Value: models.DEFAULT_RELAY6, Usage: "ipv6 address of the relay", EnvVars: []string{"CROC_RELAY6"}},
&cli.StringFlag{Name: "out", Value: ".", Usage: "specify an output folder to receive the file"}, &cli.StringFlag{Name: "out", Value: ".", Usage: "specify an output folder to receive the file"},
@ -174,6 +175,7 @@ func send(c *cli.Context) (err error) {
RelayAddress6: c.String("relay6"), RelayAddress6: c.String("relay6"),
Stdout: c.Bool("stdout"), Stdout: c.Bool("stdout"),
DisableLocal: c.Bool("no-local"), DisableLocal: c.Bool("no-local"),
OnlyLocal: c.Bool("local"),
RelayPorts: strings.Split(c.String("ports"), ","), RelayPorts: strings.Split(c.String("ports"), ","),
Ask: c.Bool("ask"), Ask: c.Bool("ask"),
NoMultiplexing: c.Bool("no-multi"), NoMultiplexing: c.Bool("no-multi"),
@ -373,6 +375,7 @@ func receive(c *cli.Context) (err error) {
Stdout: c.Bool("stdout"), Stdout: c.Bool("stdout"),
Ask: c.Bool("ask"), Ask: c.Bool("ask"),
RelayPassword: determinePass(c), RelayPassword: determinePass(c),
OnlyLocal: c.Bool("local"),
} }
if crocOptions.RelayAddress != models.DEFAULT_RELAY { if crocOptions.RelayAddress != models.DEFAULT_RELAY {
crocOptions.RelayAddress6 = "" crocOptions.RelayAddress6 = ""

View File

@ -60,6 +60,7 @@ type Options struct {
NoPrompt bool NoPrompt bool
NoMultiplexing bool NoMultiplexing bool
DisableLocal bool DisableLocal bool
OnlyLocal bool
Ask bool Ask bool
SendingText bool SendingText bool
NoCompress bool NoCompress bool
@ -372,88 +373,90 @@ func (c *Client) Send(options TransferOptions) (err error) {
go c.transferOverLocalRelay(options, errchan) go c.transferOverLocalRelay(options, errchan)
} }
go func() { if !c.Options.OnlyLocal {
var ipaddr, banner string go func() {
var conn *comm.Comm var ipaddr, banner string
durations := []time.Duration{100 * time.Millisecond, 5 * time.Second} var conn *comm.Comm
for i, address := range []string{c.Options.RelayAddress6, c.Options.RelayAddress} { durations := []time.Duration{100 * time.Millisecond, 5 * time.Second}
if address == "" { for i, address := range []string{c.Options.RelayAddress6, c.Options.RelayAddress} {
continue if address == "" {
} continue
host, port, _ := net.SplitHostPort(address)
log.Debugf("host: '%s', port: '%s'", host, port)
// Default port to :9009
if port == "" {
host = address
port = "9009"
}
log.Debugf("got host '%v' and port '%v'", host, port)
address = net.JoinHostPort(host, port)
log.Debugf("trying connection to %s", address)
conn, banner, ipaddr, err = tcp.ConnectToTCPServer(address, c.Options.RelayPassword, c.Options.SharedSecret[:3], durations[i])
if err == nil {
c.Options.RelayAddress = address
break
}
log.Debugf("could not establish '%s'", address)
}
if conn == nil && err == nil {
err = fmt.Errorf("could not connect")
}
if err != nil {
err = fmt.Errorf("could not connect to %s: %w", c.Options.RelayAddress, err)
log.Debug(err)
errchan <- err
return
}
log.Debugf("banner: %s", banner)
log.Debugf("connection established: %+v", conn)
for {
log.Debug("waiting for bytes")
data, errConn := conn.Receive()
if errConn != nil {
log.Debugf("[%+v] had error: %s", conn, errConn.Error())
}
if bytes.Equal(data, []byte("ips?")) {
// recipient wants to try to connect to local ips
var ips []string
// only get local ips if the local is enabled
if !c.Options.DisableLocal {
// get list of local ips
ips, err = utils.GetLocalIPs()
if err != nil {
log.Debugf("error getting local ips: %v", err)
}
// prepend the port that is being listened to
ips = append([]string{c.Options.RelayPorts[0]}, ips...)
} }
bips, _ := json.Marshal(ips) host, port, _ := net.SplitHostPort(address)
if err := conn.Send(bips); err != nil { log.Debugf("host: '%s', port: '%s'", host, port)
log.Errorf("error sending: %v", err) // Default port to :9009
if port == "" {
host = address
port = "9009"
} }
} else if bytes.Equal(data, []byte("handshake")) { log.Debugf("got host '%v' and port '%v'", host, port)
break address = net.JoinHostPort(host, port)
} else if bytes.Equal(data, []byte{1}) { log.Debugf("trying connection to %s", address)
log.Debug("got ping") conn, banner, ipaddr, err = tcp.ConnectToTCPServer(address, c.Options.RelayPassword, c.Options.SharedSecret[:3], durations[i])
continue if err == nil {
} else { c.Options.RelayAddress = address
log.Debugf("[%+v] got weird bytes: %+v", conn, data) break
// throttle the reading }
errchan <- fmt.Errorf("gracefully refusing using the public relay") log.Debugf("could not establish '%s'", address)
}
if conn == nil && err == nil {
err = fmt.Errorf("could not connect")
}
if err != nil {
err = fmt.Errorf("could not connect to %s: %w", c.Options.RelayAddress, err)
log.Debug(err)
errchan <- err
return return
} }
} log.Debugf("banner: %s", banner)
log.Debugf("connection established: %+v", conn)
for {
log.Debug("waiting for bytes")
data, errConn := conn.Receive()
if errConn != nil {
log.Debugf("[%+v] had error: %s", conn, errConn.Error())
}
if bytes.Equal(data, []byte("ips?")) {
// recipient wants to try to connect to local ips
var ips []string
// only get local ips if the local is enabled
if !c.Options.DisableLocal {
// get list of local ips
ips, err = utils.GetLocalIPs()
if err != nil {
log.Debugf("error getting local ips: %v", err)
}
// prepend the port that is being listened to
ips = append([]string{c.Options.RelayPorts[0]}, ips...)
}
bips, _ := json.Marshal(ips)
if err := conn.Send(bips); err != nil {
log.Errorf("error sending: %v", err)
}
} else if bytes.Equal(data, []byte("handshake")) {
break
} else if bytes.Equal(data, []byte{1}) {
log.Debug("got ping")
continue
} else {
log.Debugf("[%+v] got weird bytes: %+v", conn, data)
// throttle the reading
errchan <- fmt.Errorf("gracefully refusing using the public relay")
return
}
}
c.conn[0] = conn c.conn[0] = conn
c.Options.RelayPorts = strings.Split(banner, ",") c.Options.RelayPorts = strings.Split(banner, ",")
if c.Options.NoMultiplexing { if c.Options.NoMultiplexing {
log.Debug("no multiplexing") log.Debug("no multiplexing")
c.Options.RelayPorts = []string{c.Options.RelayPorts[0]} c.Options.RelayPorts = []string{c.Options.RelayPorts[0]}
} }
c.ExternalIP = ipaddr c.ExternalIP = ipaddr
log.Debug("exchanged header message") log.Debug("exchanged header message")
errchan <- c.transfer(options) errchan <- c.transfer(options)
}() }()
}
err = <-errchan err = <-errchan
if err == nil { if err == nil {
@ -480,6 +483,10 @@ func (c *Client) Receive() (err error) {
// recipient will look for peers first // recipient will look for peers first
// and continue if it doesn't find any within 100 ms // and continue if it doesn't find any within 100 ms
usingLocal := false usingLocal := false
if c.Options.OnlyLocal {
c.Options.RelayAddress = ""
c.Options.RelayAddress6 = ""
}
if !c.Options.DisableLocal { if !c.Options.DisableLocal {
log.Debug("attempt to discover peers") log.Debug("attempt to discover peers")
var discoveries []peerdiscovery.Discovered var discoveries []peerdiscovery.Discovered
@ -544,6 +551,7 @@ func (c *Client) Receive() (err error) {
} }
var banner string var banner string
durations := []time.Duration{100 * time.Millisecond, 5 * time.Second} durations := []time.Duration{100 * time.Millisecond, 5 * time.Second}
err = fmt.Errorf("found no addresses to connect")
for i, address := range []string{c.Options.RelayAddress6, c.Options.RelayAddress} { for i, address := range []string{c.Options.RelayAddress6, c.Options.RelayAddress} {
if address == "" { if address == "" {
continue continue