diff --git a/src/cli/cli.go b/src/cli/cli.go index 7543208..d75fea9 100644 --- a/src/cli/cli.go +++ b/src/cli/cli.go @@ -13,6 +13,7 @@ import ( "time" "github.com/schollz/croc/v6/src/croc" + "github.com/schollz/croc/v6/src/tcp" "github.com/schollz/croc/v6/src/utils" "github.com/urfave/cli" ) @@ -47,12 +48,21 @@ func Run() (err error) { return send(c) }, }, + { + Name: "relay", + Description: "start relay", + HelpName: "croc relay", + Action: func(c *cli.Context) error { + return relay(c) + }, + }, } app.Flags = []cli.Flag{ cli.BoolFlag{Name: "debug", Usage: "increase verbosity (a lot)"}, cli.BoolFlag{Name: "yes", Usage: "automatically agree to all prompts"}, cli.BoolFlag{Name: "stdout", Usage: "redirect file to stdout"}, - cli.StringFlag{Name: "relay", Value: "198.199.67.130:6372", Usage: "address of the relay"}, + cli.StringFlag{Name: "relay", Value: "198.199.67.130", Usage: "address of the relay"}, + cli.StringFlag{Name: "ports", Value: "9009,9010,9011,9012,9013,9014,9015,9016,9017,9018", Usage: "address of the relay"}, cli.StringFlag{Name: "out", Value: ".", Usage: "specify an output folder to receive the file"}, } app.EnableBashCompletion = true @@ -153,6 +163,7 @@ func send(c *cli.Context) (err error) { Debug: c.GlobalBool("debug"), NoPrompt: c.GlobalBool("yes"), RelayAddress: c.GlobalString("relay"), + RelayPorts: strings.Split(c.GlobalString("ports"), ","), Stdout: c.GlobalBool("stdout"), }) if err != nil { @@ -189,6 +200,7 @@ func receive(c *cli.Context) (err error) { NoPrompt: c.GlobalBool("yes"), RelayAddress: c.GlobalString("relay"), Stdout: c.GlobalBool("stdout"), + RelayPorts: strings.Split(c.GlobalString("ports"), ","), }) if err != nil { return @@ -197,9 +209,25 @@ func receive(c *cli.Context) (err error) { return } -// func relay(c *cli.Context) error { -// return cr.Relay() -// } +func relay(c *cli.Context) (err error) { + debugString := "warn" + if c.GlobalBool("debug") { + debugString = "debug" + } + ports := strings.Split(c.GlobalString("ports"), ",") + for i, port := range ports { + if i == 0 { + continue + } + go func(portStr string) { + err = tcp.Run(debugString, portStr) + if err != nil { + panic(err) + } + }(port) + } + return tcp.Run(debugString, ports[0]) +} // func dirSize(path string) (int64, error) { // var size int64 diff --git a/src/croc/croc.go b/src/croc/croc.go index 9c2ac00..026c30f 100644 --- a/src/croc/croc.go +++ b/src/croc/croc.go @@ -71,6 +71,7 @@ type Client struct { // send / receive information of current file CurrentFile *os.File CurrentFileChunks []int64 + TotalSent int64 // tcp connections conn []*comm.Comm @@ -493,6 +494,7 @@ func (c *Client) updateState() (err error) { progressbar.OptionSetWriter(os.Stderr), progressbar.OptionThrottle(100*time.Millisecond), ) + c.TotalSent = 0 // recipient requests the file and chunks (if empty, then should receive all chunks) bRequest, _ := json.Marshal(RemoteFileRequest{ @@ -524,6 +526,7 @@ func (c *Client) updateState() (err error) { progressbar.OptionSetWriter(os.Stderr), progressbar.OptionThrottle(100*time.Millisecond), ) + c.TotalSent = 0 for i := 1; i < len(c.Options.RelayPorts); i++ { go c.sendData(i) } @@ -532,7 +535,6 @@ func (c *Client) updateState() (err error) { } func (c *Client) receiveData(i int) { - for { data, err := c.conn[i].Receive() if err != nil { @@ -554,13 +556,15 @@ func (c *Client) receiveData(i int) { positionInt64 := int64(position) c.mutex.Lock() - n, err := c.CurrentFile.WriteAt(data[8:], positionInt64) + _, err = c.CurrentFile.WriteAt(data[8:], positionInt64) c.mutex.Unlock() if err != nil { panic(err) } - c.bar.Add(n) - if c.bar.State().CurrentBytes == float64(c.FilesToTransfer[c.FilesToTransferCurrentNum].Size) { + c.bar.Add(len(data[8:])) + c.TotalSent += int64(len(data[8:])) + log.Debugf("state: %+v", c.bar.State()) + if c.TotalSent == c.FilesToTransfer[c.FilesToTransferCurrentNum].Size { log.Debug("finished receiving!") c.CurrentFile.Close() log.Debug("sending close-sender") @@ -577,6 +581,9 @@ func (c *Client) receiveData(i int) { } func (c *Client) sendData(i int) { + defer func() { + log.Debugf("finished with %d", i) + }() pathToFile := path.Join( c.FilesToTransfer[c.FilesToTransferCurrentNum].FolderSource, c.FilesToTransfer[c.FilesToTransferCurrentNum].Name, @@ -592,7 +599,7 @@ func (c *Client) sendData(i int) { curi := float64(0) for { // Read file - data := make([]byte, 1000) + data := make([]byte, 40000) n, err := f.Read(data) if err != nil { if err == io.EOF { @@ -619,6 +626,9 @@ func (c *Client) sendData(i int) { panic(err) } c.bar.Add(n) + c.TotalSent += int64(n) + log.Debug(c.TotalSent) + // time.Sleep(10 * time.Millisecond) } curi++ diff --git a/src/tcp/tcp.go b/src/tcp/tcp.go index 404a03e..01be938 100644 --- a/src/tcp/tcp.go +++ b/src/tcp/tcp.go @@ -34,14 +34,14 @@ type roomMap struct { } // Run starts a tcp listener, run async -func Run(debugLevel, port string) { +func Run(debugLevel, port string) (err error) { s := new(server) s.port = port s.debugLevel = debugLevel - s.start() + return s.start() } -func (s *server) start() { +func (s *server) start() (err error) { logger.SetLogLevel(s.debugLevel) s.rooms.Lock() s.rooms.rooms = make(map[string]roomInfo) @@ -61,10 +61,11 @@ func (s *server) start() { } }() - err := s.run() + err = s.run() if err != nil { log.Error(err) - } + } + return } func (s *server) run() (err error) {