diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index e0e4bbc3..330daea2 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -27,7 +27,7 @@ jobs:
- name: Setup Go
uses: actions/setup-go@v4
with:
- go-version: '1.22'
+ go-version: '1.21'
- name: Prepare source tarball
run: |
git clone -b ${{ github.event.release.name }} --depth 1 https://github.com/schollz/croc croc-${{ github.event.release.name }}
@@ -39,6 +39,10 @@ jobs:
zip croc_${{ github.event.release.name }}_Windows-64bit.zip croc.exe
GOOS=windows GOARCH=386 go build -ldflags="-s -w" -o croc.exe
zip croc_${{ github.event.release.name }}_Windows-32bit.zip croc.exe
+ GOOS=windows GOARCH=arm go build -ldflags="-s -w" -o croc.exe
+ zip croc_${{ github.event.release.name }}_Windows-ARM.zip croc.exe
+ GOOS=windows GOARCH=arm64 go build -ldflags="-s -w" -o croc.exe
+ zip croc_${{ github.event.release.name }}_Windows-ARM64.zip croc.exe
GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o croc
upx --brute croc
tar -czvf croc_${{ github.event.release.name }}_Linux-64bit.tar.gz croc
@@ -60,6 +64,8 @@ jobs:
sha256sum croc_${{ github.event.release.name }}_src.tar.gz >> croc_${{ github.event.release.name }}_checksums.txt
sha256sum croc_${{ github.event.release.name }}_Windows-64bit.zip >> croc_${{ github.event.release.name }}_checksums.txt
sha256sum croc_${{ github.event.release.name }}_Windows-32bit.zip >> croc_${{ github.event.release.name }}_checksums.txt
+ sha256sum croc_${{ github.event.release.name }}_Windows-ARM.zip >> croc_${{ github.event.release.name }}_checksums.txt
+ sha256sum croc_${{ github.event.release.name }}_Windows-ARM64.zip >> croc_${{ github.event.release.name }}_checksums.txt
sha256sum croc_${{ github.event.release.name }}_Windows7-64bit.zip >> croc_${{ github.event.release.name }}_checksums.txt
sha256sum croc_${{ github.event.release.name }}_Windows7-32bit.zip >> croc_${{ github.event.release.name }}_checksums.txt
sha256sum croc_${{ github.event.release.name }}_Linux-64bit.tar.gz >> croc_${{ github.event.release.name }}_checksums.txt
@@ -76,6 +82,8 @@ jobs:
croc_${{ github.event.release.name }}_src.tar.gz
croc_${{ github.event.release.name }}_Windows-64bit.zip
croc_${{ github.event.release.name }}_Windows-32bit.zip
+ croc_${{ github.event.release.name }}_Windows-ARM.zip
+ croc_${{ github.event.release.name }}_Windows-ARM64.zip
croc_${{ github.event.release.name }}_Windows7-64bit.zip
croc_${{ github.event.release.name }}_Windows7-32bit.zip
croc_${{ github.event.release.name }}_Linux-64bit.tar.gz
diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml
index 6e61bf53..1e3ae32b 100644
--- a/.github/workflows/stale.yml
+++ b/.github/workflows/stale.yml
@@ -18,7 +18,7 @@ jobs:
pull-requests: write
steps:
- - uses: actions/stale@v5
+ - uses: actions/stale@v9
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: 'Stale issue message'
diff --git a/README.md b/README.md
index 624b330d..009b4a3d 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
src="https://user-images.githubusercontent.com/6550035/46709024-9b23ad00-cbf6-11e8-9fb2-ca8b20b7dbec.jpg"
width="408px" border="0" alt="croc">
-
+
0 {
- crocOptions.BasePort = rememberedOptions.BasePort
- }
- if !c.IsSet("transfers") && rememberedOptions.TransferPorts > 0 {
- crocOptions.TransferPorts = rememberedOptions.TransferPorts
+ if !c.IsSet("ports") && len(rememberedOptions.RelayPorts) > 0 {
+ crocOptions.RelayPorts = rememberedOptions.RelayPorts
}
if !c.IsSet("code") {
crocOptions.SharedSecret = rememberedOptions.SharedSecret
diff --git a/src/croc/croc.go b/src/croc/croc.go
index 1da74297..61262c7b 100644
--- a/src/croc/croc.go
+++ b/src/croc/croc.go
@@ -60,8 +60,7 @@ type Options struct {
Debug bool
RelayAddress string
RelayAddress6 string
- BasePort int
- TransferPorts int
+ RelayPorts []string
RelayPassword string
Stdout bool
NoPrompt bool
@@ -530,26 +529,21 @@ func (c *Client) sendCollectFiles(filesInfo []FileInfo) (err error) {
func (c *Client) setupLocalRelay() {
// setup the relay locally
- basePort := c.Options.BasePort
- transferPorts := c.Options.TransferPorts
- ports := make([]string, transferPorts+1)
- for i := range ports {
- ports[i] = strconv.Itoa(basePort + i)
- }
- openPorts := utils.FindOpenPorts("127.0.0.1", basePort, transferPorts+1)
- if len(openPorts) < len(ports) {
+ firstPort, _ := strconv.Atoi(c.Options.RelayPorts[0])
+ openPorts := utils.FindOpenPorts("127.0.0.1", firstPort, len(c.Options.RelayPorts))
+ if len(openPorts) < len(c.Options.RelayPorts) {
panic("not enough open ports to run local relay")
}
for i, port := range openPorts {
- ports[i] = fmt.Sprint(port)
+ c.Options.RelayPorts[i] = fmt.Sprint(port)
}
- for _, port := range ports {
+ for _, port := range c.Options.RelayPorts {
go func(portStr string) {
debugString := "warn"
if c.Options.Debug {
debugString = "debug"
}
- err := tcp.Run(debugString, "127.0.0.1", portStr, c.Options.RelayPassword, fmt.Sprintf(strconv.Itoa(basePort)+","+strconv.Itoa(transferPorts)))
+ err := tcp.Run(debugString, "127.0.0.1", portStr, c.Options.RelayPassword, strings.Join(c.Options.RelayPorts[1:], ","))
if err != nil {
panic(err)
}
@@ -568,7 +562,7 @@ func (c *Client) broadcastOnLocalNetwork(useipv6 bool) {
// look for peers first
settings := peerdiscovery.Settings{
Limit: -1,
- Payload: []byte("croc" + strconv.Itoa(c.Options.BasePort)),
+ Payload: []byte("croc" + c.Options.RelayPorts[0]),
Delay: 20 * time.Millisecond,
TimeLimit: timeLimit,
}
@@ -588,10 +582,10 @@ func (c *Client) transferOverLocalRelay(errchan chan<- error) {
time.Sleep(500 * time.Millisecond)
log.Debug("establishing connection")
var banner string
- conn, banner, ipaddr, err := tcp.ConnectToTCPServer("127.0.0.1:"+strconv.Itoa(c.Options.BasePort), c.Options.RelayPassword, c.Options.SharedSecret[:3])
+ conn, banner, ipaddr, err := tcp.ConnectToTCPServer("127.0.0.1:"+c.Options.RelayPorts[0], c.Options.RelayPassword, c.Options.SharedSecret[:3])
log.Debugf("banner: %s", banner)
if err != nil {
- err = fmt.Errorf("could not connect to 127.0.0.1:%s: %w", c.Options.BasePort, err)
+ err = fmt.Errorf("could not connect to 127.0.0.1:%s: %w", c.Options.RelayPorts[0], err)
log.Debug(err)
// not really an error because it will try to connect over the actual relay
return
@@ -610,26 +604,10 @@ func (c *Client) transferOverLocalRelay(errchan chan<- error) {
c.conn[0] = conn
log.Debug("exchanged header message")
c.Options.RelayAddress = "127.0.0.1"
- var basePort, transferPorts int
- banner_split := strings.Split(banner, ",")
- if len(banner_split) != 2 {
- panic(fmt.Sprintf("Expected port and number of transfer ports in banner: %v", banner))
- }
- basePort, err = strconv.Atoi(banner_split[0])
- if err == nil {
- c.Options.BasePort = basePort
- } else {
- panic(fmt.Sprintf("could not get transfer ports: %v", err))
- }
- transferPorts, err = strconv.Atoi(banner_split[1])
- if err == nil {
- c.Options.TransferPorts = transferPorts
- } else {
- panic(fmt.Sprintf("could not get transfer ports: %v", err))
- }
+ c.Options.RelayPorts = strings.Split(banner, ",")
if c.Options.NoMultiplexing {
log.Debug("no multiplexing")
- c.Options.TransferPorts = 1
+ c.Options.RelayPorts = []string{c.Options.RelayPorts[0]}
}
c.ExternalIP = ipaddr
errchan <- c.transfer()
@@ -727,7 +705,7 @@ func (c *Client) Send(filesInfo []FileInfo, emptyFoldersToTransfer []FileInfo, t
log.Debugf("error getting local ips: %v", err)
}
// prepend the port that is being listened to
- ips = append([]string{strconv.Itoa(c.Options.BasePort)}, ips...)
+ ips = append([]string{c.Options.RelayPorts[0]}, ips...)
}
bips, _ := json.Marshal(ips)
if err = conn.Send(bips); err != nil {
@@ -747,26 +725,10 @@ func (c *Client) Send(filesInfo []FileInfo, emptyFoldersToTransfer []FileInfo, t
}
c.conn[0] = conn
- var basePort, transferPorts int
- banner_split := strings.Split(banner, ",")
- if len(banner_split) != 2 {
- panic(fmt.Sprintf("Expected port and number of transfer ports in banner: %v", banner))
- }
- basePort, err = strconv.Atoi(banner_split[0])
- if err == nil {
- c.Options.BasePort = basePort
- } else {
- panic(fmt.Sprintf("could not get transfer ports: %v", err))
- }
- transferPorts, err = strconv.Atoi(banner_split[1])
- if err == nil {
- c.Options.TransferPorts = transferPorts
- } else {
- panic(fmt.Sprintf("could not get transfer ports: %v", err))
- }
+ c.Options.RelayPorts = strings.Split(banner, ",")
if c.Options.NoMultiplexing {
log.Debug("no multiplexing")
- c.Options.TransferPorts = 1
+ c.Options.RelayPorts = []string{c.Options.RelayPorts[0]}
}
c.ExternalIP = ipaddr
log.Debug("exchanged header message")
@@ -986,26 +948,10 @@ func (c *Client) Receive() (err error) {
if err = c.conn[0].Send(handshakeRequest); err != nil {
log.Errorf("handshake send error: %v", err)
}
- var basePort, transferPorts int
- banner_split := strings.Split(banner, ",")
- if len(banner_split) != 2 {
- panic(fmt.Sprintf("Expected port and number of transfer ports in banner: %v", banner))
- }
- basePort, err = strconv.Atoi(banner_split[0])
- if err == nil {
- c.Options.BasePort = basePort
- } else {
- panic(fmt.Sprintf("could not get transfer ports: %v", err))
- }
- transferPorts, err = strconv.Atoi(banner_split[1])
- if err == nil {
- c.Options.TransferPorts = transferPorts
- } else {
- panic(fmt.Sprintf("could not get transfer ports: %v", err))
- }
+ c.Options.RelayPorts = strings.Split(banner, ",")
if c.Options.NoMultiplexing {
log.Debug("no multiplexing")
- c.Options.TransferPorts = 1
+ c.Options.RelayPorts = []string{c.Options.RelayPorts[0]}
}
log.Debug("exchanged header message")
fmt.Fprintf(os.Stderr, "\rsecuring channel...")
@@ -1098,7 +1044,7 @@ func (c *Client) transfer() (err error) {
if err = os.Remove(pathToFile); err != nil {
log.Warnf("error removing %s: %v", pathToFile, err)
}
- fmt.Print("\n")
+ fmt.Fprint(os.Stderr, "\n")
}
if err != nil && strings.Contains(err.Error(), "pake not successful") {
log.Debugf("pake error: %s", err.Error())
@@ -1309,9 +1255,9 @@ func (c *Client) processMessagePake(m message.Message) (err error) {
// connects to the other ports of the server for transfer
var wg sync.WaitGroup
- wg.Add(c.Options.TransferPorts + 1)
- for i := 0; i <= c.Options.TransferPorts; i++ {
- log.Debugf("port: [%d]", c.Options.BasePort+i)
+ wg.Add(len(c.Options.RelayPorts))
+ for i := 0; i < len(c.Options.RelayPorts); i++ {
+ log.Debugf("port: [%s]", c.Options.RelayPorts[i])
go func(j int) {
defer wg.Done()
var host string
@@ -1324,7 +1270,7 @@ func (c *Client) processMessagePake(m message.Message) (err error) {
return
}
}
- server := net.JoinHostPort(host, strconv.Itoa(c.Options.BasePort+j))
+ server := net.JoinHostPort(host, c.Options.RelayPorts[j])
log.Debugf("connecting to %s", server)
c.conn[j+1], _, _, err = tcp.ConnectToTCPServer(
server,
@@ -1802,7 +1748,7 @@ func (c *Client) updateState() (err error) {
if err != nil {
return
}
- for i := 0; i <= c.Options.TransferPorts; i++ {
+ for i := 0; i < len(c.Options.RelayPorts); i++ {
log.Debugf("starting sending over comm %d", i)
go c.sendData(i)
}
@@ -1915,7 +1861,7 @@ func (c *Client) sendData(i int) {
defer func() {
log.Debugf("finished with %d", i)
c.numfinished++
- if c.numfinished == c.Options.TransferPorts+1 {
+ if c.numfinished == len(c.Options.RelayPorts) {
log.Debug("closing file")
if err := c.fread.Close(); err != nil {
log.Errorf("error closing file: %v", err)
@@ -1939,7 +1885,7 @@ func (c *Client) sendData(i int) {
time.Sleep(r.Delay())
}
- if math.Mod(curi, float64(c.Options.TransferPorts+1)) == float64(i) {
+ if math.Mod(curi, float64(len(c.Options.RelayPorts))) == float64(i) {
// check to see if this is a chunk that the recipient wants
usableChunk := true
c.mutex.Lock()
diff --git a/src/croc/croc_test.go b/src/croc/croc_test.go
index 0a4447d6..445ec5af 100644
--- a/src/croc/croc_test.go
+++ b/src/croc/croc_test.go
@@ -18,7 +18,7 @@ import (
func init() {
log.SetLevel("trace")
- go tcp.Run("debug", "127.0.0.1", "8281", "pass123", "8281,4")
+ go tcp.Run("debug", "127.0.0.1", "8281", "pass123", "8282,8283,8284,8285")
go tcp.Run("debug", "127.0.0.1", "8282", "pass123")
go tcp.Run("debug", "127.0.0.1", "8283", "pass123")
go tcp.Run("debug", "127.0.0.1", "8284", "pass123")
@@ -35,7 +35,7 @@ func TestCrocReadme(t *testing.T) {
SharedSecret: "8123-testingthecroc",
Debug: true,
RelayAddress: "127.0.0.1:8281",
- BasePort: 8281,
+ RelayPorts: []string{"8281"},
RelayPassword: "pass123",
Stdout: false,
NoPrompt: true,
@@ -102,7 +102,7 @@ func TestCrocEmptyFolder(t *testing.T) {
SharedSecret: "8123-testingthecroc",
Debug: true,
RelayAddress: "127.0.0.1:8281",
- BasePort: 8281,
+ RelayPorts: []string{"8281"},
RelayPassword: "pass123",
Stdout: false,
NoPrompt: true,
@@ -169,7 +169,7 @@ func TestCrocSymlink(t *testing.T) {
SharedSecret: "8124-testingthecroc",
Debug: true,
RelayAddress: "127.0.0.1:8281",
- BasePort: 8281,
+ RelayPorts: []string{"8281"},
RelayPassword: "pass123",
Stdout: false,
NoPrompt: true,
@@ -271,8 +271,7 @@ func TestCrocLocal(t *testing.T) {
SharedSecret: "8123-testingthecroc",
Debug: true,
RelayAddress: "127.0.0.1:8181",
- BasePort: 8181,
- TransferPorts: 1,
+ RelayPorts: []string{"8181", "8182"},
RelayPassword: "pass123",
Stdout: true,
NoPrompt: true,
@@ -352,8 +351,7 @@ func TestCrocError(t *testing.T) {
SharedSecret: "8123-testingthecroc2",
Debug: true,
RelayAddress: "doesntexistok.com:8381",
- BasePort: 8381,
- TransferPorts: 1,
+ RelayPorts: []string{"8381", "8382"},
RelayPassword: "pass123",
Stdout: true,
NoPrompt: true,
diff --git a/src/install/default.txt b/src/install/default.txt
index a66571bc..cbef112f 100644
--- a/src/install/default.txt
+++ b/src/install/default.txt
@@ -528,7 +528,7 @@ main() {
local autocomplete_install_rcode
croc_bin_name="croc"
- croc_version="9.6.9"
+ croc_version="9.6.11"
croc_dl_ext="tar.gz"
croc_base_url="https://github.com/schollz/croc/releases/download"
prefix="${1}"