Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5c75a319be | ||
|
|
fcbeaa737f | ||
|
|
b8b41fad30 | ||
|
|
cf898bef18 | ||
|
|
0fca426ffe |
|
|
@ -1,4 +1,5 @@
|
||||||
# Binaries
|
# Binaries
|
||||||
|
src2
|
||||||
/croc
|
/croc
|
||||||
/croc.exe
|
/croc.exe
|
||||||
zsh_autocomplete
|
zsh_autocomplete
|
||||||
|
|
|
||||||
16
README.md
16
README.md
|
|
@ -4,7 +4,7 @@
|
||||||
src="https://user-images.githubusercontent.com/6550035/46709024-9b23ad00-cbf6-11e8-9fb2-ca8b20b7dbec.jpg"
|
src="https://user-images.githubusercontent.com/6550035/46709024-9b23ad00-cbf6-11e8-9fb2-ca8b20b7dbec.jpg"
|
||||||
width="408px" border="0" alt="croc">
|
width="408px" border="0" alt="croc">
|
||||||
<br>
|
<br>
|
||||||
<a href="https://github.com/schollz/croc/releases/latest"><img src="https://img.shields.io/badge/version-v10.1.1-brightgreen.svg?style=flat-square" alt="Version"></a>
|
<a href="https://github.com/schollz/croc/releases/latest"><img src="https://img.shields.io/badge/version-v10.0.13-brightgreen.svg?style=flat-square" alt="Version"></a>
|
||||||
<a href="https://github.com/schollz/croc/actions/workflows/ci.yml"><img
|
<a href="https://github.com/schollz/croc/actions/workflows/ci.yml"><img
|
||||||
src="https://github.com/schollz/croc/actions/workflows/ci.yml/badge.svg" alt="Build
|
src="https://github.com/schollz/croc/actions/workflows/ci.yml/badge.svg" alt="Build
|
||||||
Status"></a>
|
Status"></a>
|
||||||
|
|
@ -104,19 +104,7 @@ On FreeBSD you can install with `pkg`:
|
||||||
pkg install croc
|
pkg install croc
|
||||||
```
|
```
|
||||||
|
|
||||||
On Linux, macOS, and Windows you can install from [conda-forge](https://github.com/conda-forge/croc-feedstock/) globally with [`pixi`](https://pixi.sh/):
|
Or, you can [install Go](https://golang.org/dl/) and build from source (requires Go 1.17+):
|
||||||
|
|
||||||
```
|
|
||||||
pixi global install croc
|
|
||||||
```
|
|
||||||
|
|
||||||
or into a particular environment with [`conda`](https://docs.conda.io/projects/conda/):
|
|
||||||
|
|
||||||
```
|
|
||||||
conda install --channel conda-forge croc
|
|
||||||
```
|
|
||||||
|
|
||||||
Or, you can [install Go](https://golang.org/dl/) and build from source (requires Go 1.17+):
|
|
||||||
|
|
||||||
```
|
```
|
||||||
go install github.com/schollz/croc/v10@latest
|
go install github.com/schollz/croc/v10@latest
|
||||||
|
|
|
||||||
16
go.mod
16
go.mod
|
|
@ -16,14 +16,14 @@ require (
|
||||||
github.com/schollz/logger v1.2.0
|
github.com/schollz/logger v1.2.0
|
||||||
github.com/schollz/pake/v3 v3.0.5
|
github.com/schollz/pake/v3 v3.0.5
|
||||||
github.com/schollz/peerdiscovery v1.7.5
|
github.com/schollz/peerdiscovery v1.7.5
|
||||||
github.com/schollz/progressbar/v3 v3.17.1
|
github.com/schollz/progressbar/v3 v3.16.1
|
||||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
|
|
||||||
github.com/stretchr/testify v1.9.0
|
github.com/stretchr/testify v1.9.0
|
||||||
golang.org/x/crypto v0.29.0
|
golang.org/x/crypto v0.28.0
|
||||||
golang.org/x/net v0.31.0
|
golang.org/x/net v0.30.0
|
||||||
golang.org/x/sys v0.27.0
|
golang.org/x/sys v0.26.0
|
||||||
golang.org/x/term v0.26.0
|
golang.org/x/term v0.25.0
|
||||||
golang.org/x/time v0.8.0
|
golang.org/x/time v0.7.0
|
||||||
|
gortc.io/stun v1.23.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
|
@ -37,3 +37,5 @@ require (
|
||||||
github.com/twmb/murmur3 v1.1.8 // indirect
|
github.com/twmb/murmur3 v1.1.8 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
|
replace gortc.io/stun => github.com/gortc/stun v1.23.0
|
||||||
|
|
|
||||||
28
go.sum
28
go.sum
|
|
@ -20,6 +20,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
||||||
github.com/denisbrodbeck/machineid v1.0.1 h1:geKr9qtkB876mXguW2X6TU4ZynleN6ezuMSRhl4D7AQ=
|
github.com/denisbrodbeck/machineid v1.0.1 h1:geKr9qtkB876mXguW2X6TU4ZynleN6ezuMSRhl4D7AQ=
|
||||||
github.com/denisbrodbeck/machineid v1.0.1/go.mod h1:dJUwb7PTidGDeYyUBmXZ2GphQBbjJCrnectwCyxcUSI=
|
github.com/denisbrodbeck/machineid v1.0.1/go.mod h1:dJUwb7PTidGDeYyUBmXZ2GphQBbjJCrnectwCyxcUSI=
|
||||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
|
github.com/gortc/stun v1.23.0 h1:/hkB8P0DeDfiVf3khHSMSTRpldFMqiuddn2XhaUPOkM=
|
||||||
|
github.com/gortc/stun v1.23.0/go.mod h1:XD5lpONVyjvV3BgOyJFNo0iv6R2oZB4L+weMqxts+zg=
|
||||||
github.com/kalafut/imohash v1.1.0 h1:Lldcmx0SXgMSoABB2WBD8mTgf0OlVnISn2Dyrfg2Ep8=
|
github.com/kalafut/imohash v1.1.0 h1:Lldcmx0SXgMSoABB2WBD8mTgf0OlVnISn2Dyrfg2Ep8=
|
||||||
github.com/kalafut/imohash v1.1.0/go.mod h1:6cn9lU0Sj8M4eu9UaQm1kR/5y3k/ayB68yntRhGloL4=
|
github.com/kalafut/imohash v1.1.0/go.mod h1:6cn9lU0Sj8M4eu9UaQm1kR/5y3k/ayB68yntRhGloL4=
|
||||||
github.com/magisterquis/connectproxy v0.0.0-20200725203833-3582e84f0c9b h1:xZ59n7Frzh8CwyfAapUZLSg+gXH5m63YEaFCMpDHhpI=
|
github.com/magisterquis/connectproxy v0.0.0-20200725203833-3582e84f0c9b h1:xZ59n7Frzh8CwyfAapUZLSg+gXH5m63YEaFCMpDHhpI=
|
||||||
|
|
@ -47,11 +49,9 @@ github.com/schollz/pake/v3 v3.0.5 h1:MnZVdI987lkjln9BSx/zUb724TZISa2jbO+dPj6BvgQ
|
||||||
github.com/schollz/pake/v3 v3.0.5/go.mod h1:OGbG6htRwSKo6V8R5tg61ufpFmZM1b/PrrSp6g2ZLLc=
|
github.com/schollz/pake/v3 v3.0.5/go.mod h1:OGbG6htRwSKo6V8R5tg61ufpFmZM1b/PrrSp6g2ZLLc=
|
||||||
github.com/schollz/peerdiscovery v1.7.5 h1:0cEhO+o8i4fpeKBwl7u0UY3Kt3XVt5fSzS4rg17ZPb4=
|
github.com/schollz/peerdiscovery v1.7.5 h1:0cEhO+o8i4fpeKBwl7u0UY3Kt3XVt5fSzS4rg17ZPb4=
|
||||||
github.com/schollz/peerdiscovery v1.7.5/go.mod h1:Crht2FOfD1/eL3U/AIM0vvwVZDPePlBgSX3Xw+TnJoE=
|
github.com/schollz/peerdiscovery v1.7.5/go.mod h1:Crht2FOfD1/eL3U/AIM0vvwVZDPePlBgSX3Xw+TnJoE=
|
||||||
github.com/schollz/progressbar/v3 v3.17.1 h1:bI1MTaoQO+v5kzklBjYNRQLoVpe0zbyRZNK6DFkVC5U=
|
github.com/schollz/progressbar/v3 v3.16.1 h1:RnF1neWZFzLCoGx8yp1yF7SDl4AzNDI5y4I0aUJRrZQ=
|
||||||
github.com/schollz/progressbar/v3 v3.17.1/go.mod h1:RzqpnsPQNjUyIgdglUjRLgD7sVnxN1wpmBMV+UiEbL4=
|
github.com/schollz/progressbar/v3 v3.16.1/go.mod h1:I2ILR76gz5VXqYMIY/LdLecvMHDPVcQm3W/MSKi1TME=
|
||||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0=
|
|
||||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M=
|
|
||||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ=
|
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ=
|
||||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
|
@ -71,8 +71,8 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY
|
||||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||||
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
|
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
|
||||||
golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ=
|
golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
|
||||||
golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg=
|
golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
|
|
@ -87,8 +87,8 @@ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
||||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||||
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
|
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
|
||||||
golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo=
|
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
|
||||||
golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM=
|
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
|
@ -109,8 +109,8 @@ golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
|
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
|
||||||
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
|
|
@ -120,8 +120,8 @@ golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
|
||||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||||
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
||||||
golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8=
|
golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8=
|
||||||
golang.org/x/term v0.26.0 h1:WEQa6V3Gja/BhNxg540hBip/kkaYtRg3cxg4oXSw4AU=
|
golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24=
|
||||||
golang.org/x/term v0.26.0/go.mod h1:Si5m1o57C5nBNQo5z1iq+XDijt21BDBDp2bK0QI8e3E=
|
golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
|
|
@ -131,8 +131,8 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||||
golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg=
|
golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ=
|
||||||
golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ func Run() (err error) {
|
||||||
app := cli.NewApp()
|
app := cli.NewApp()
|
||||||
app.Name = "croc"
|
app.Name = "croc"
|
||||||
if Version == "" {
|
if Version == "" {
|
||||||
Version = "v10.1.0"
|
Version = "v10.0.13"
|
||||||
}
|
}
|
||||||
app.Version = Version
|
app.Version = Version
|
||||||
app.Compiled = time.Now()
|
app.Compiled = time.Now()
|
||||||
|
|
@ -77,7 +77,6 @@ func Run() (err error) {
|
||||||
&cli.BoolFlag{Name: "git", Usage: "enable .gitignore respect / don't send ignored files"},
|
&cli.BoolFlag{Name: "git", Usage: "enable .gitignore respect / don't send ignored files"},
|
||||||
&cli.IntFlag{Name: "port", Value: 9009, Usage: "base port for the relay"},
|
&cli.IntFlag{Name: "port", Value: 9009, Usage: "base port for the relay"},
|
||||||
&cli.IntFlag{Name: "transfers", Value: 4, Usage: "number of ports to use for transfers"},
|
&cli.IntFlag{Name: "transfers", Value: 4, Usage: "number of ports to use for transfers"},
|
||||||
&cli.BoolFlag{Name: "qrcode", Aliases: []string{"qr"}, Usage: "show receive code as a qrcode"},
|
|
||||||
},
|
},
|
||||||
HelpName: "croc send",
|
HelpName: "croc send",
|
||||||
Action: send,
|
Action: send,
|
||||||
|
|
@ -303,7 +302,6 @@ func send(c *cli.Context) (err error) {
|
||||||
ThrottleUpload: c.String("throttleUpload"),
|
ThrottleUpload: c.String("throttleUpload"),
|
||||||
ZipFolder: c.Bool("zip"),
|
ZipFolder: c.Bool("zip"),
|
||||||
GitIgnore: c.Bool("git"),
|
GitIgnore: c.Bool("git"),
|
||||||
ShowQrCode: c.Bool("qrcode"),
|
|
||||||
MulticastAddress: c.String("multicast"),
|
MulticastAddress: c.String("multicast"),
|
||||||
}
|
}
|
||||||
if crocOptions.RelayAddress != models.DEFAULT_RELAY {
|
if crocOptions.RelayAddress != models.DEFAULT_RELAY {
|
||||||
|
|
|
||||||
276
src/croc/croc.go
276
src/croc/croc.go
|
|
@ -27,7 +27,6 @@ import (
|
||||||
"github.com/schollz/pake/v3"
|
"github.com/schollz/pake/v3"
|
||||||
"github.com/schollz/peerdiscovery"
|
"github.com/schollz/peerdiscovery"
|
||||||
"github.com/schollz/progressbar/v3"
|
"github.com/schollz/progressbar/v3"
|
||||||
"github.com/skip2/go-qrcode"
|
|
||||||
"golang.org/x/term"
|
"golang.org/x/term"
|
||||||
"golang.org/x/time/rate"
|
"golang.org/x/time/rate"
|
||||||
|
|
||||||
|
|
@ -50,7 +49,7 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Debug toggles debug mode
|
// Debug toggles debug mode
|
||||||
func Debug(debug bool) {
|
func Trace(debug bool) {
|
||||||
if debug {
|
if debug {
|
||||||
log.SetLevel("debug")
|
log.SetLevel("debug")
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -86,7 +85,6 @@ type Options struct {
|
||||||
TestFlag bool
|
TestFlag bool
|
||||||
GitIgnore bool
|
GitIgnore bool
|
||||||
MulticastAddress string
|
MulticastAddress string
|
||||||
ShowQrCode bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type SimpleMessage struct {
|
type SimpleMessage struct {
|
||||||
|
|
@ -194,7 +192,7 @@ func New(ops Options) (c *Client, err error) {
|
||||||
|
|
||||||
// setup basic info
|
// setup basic info
|
||||||
c.Options = ops
|
c.Options = ops
|
||||||
Debug(c.Options.Debug)
|
Trace(c.Options.Debug)
|
||||||
|
|
||||||
if len(c.Options.SharedSecret) < 6 {
|
if len(c.Options.SharedSecret) < 6 {
|
||||||
err = fmt.Errorf("code is too short")
|
err = fmt.Errorf("code is too short")
|
||||||
|
|
@ -236,7 +234,7 @@ func New(ops Options) (c *Client, err error) {
|
||||||
minBurstSize = int(uploadLimit)
|
minBurstSize = int(uploadLimit)
|
||||||
}
|
}
|
||||||
c.limiter = rate.NewLimiter(rt, minBurstSize)
|
c.limiter = rate.NewLimiter(rt, minBurstSize)
|
||||||
log.Debugf("Throttling Upload to %#v", c.limiter.Limit())
|
log.Tracef("Throttling Upload to %#v", c.limiter.Limit())
|
||||||
}
|
}
|
||||||
|
|
||||||
// initialize pake for recipient
|
// initialize pake for recipient
|
||||||
|
|
@ -505,12 +503,12 @@ func (c *Client) sendCollectFiles(filesInfo []FileInfo) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if fileInfo.Mode&os.ModeSymlink != 0 {
|
if fileInfo.Mode&os.ModeSymlink != 0 {
|
||||||
log.Debugf("%s is symlink", fileInfo.Name)
|
log.Tracef("%s is symlink", fileInfo.Name)
|
||||||
c.FilesToTransfer[i].Symlink, err = os.Readlink(fullPath)
|
c.FilesToTransfer[i].Symlink, err = os.Readlink(fullPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debugf("error getting symlink: %s", err.Error())
|
log.Tracef("error getting symlink: %s", err.Error())
|
||||||
}
|
}
|
||||||
log.Debugf("%+v", c.FilesToTransfer[i])
|
log.Tracef("%+v", c.FilesToTransfer[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.Options.HashAlgorithm == "" {
|
if c.Options.HashAlgorithm == "" {
|
||||||
|
|
@ -518,16 +516,16 @@ func (c *Client) sendCollectFiles(filesInfo []FileInfo) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
c.FilesToTransfer[i].Hash, err = utils.HashFile(fullPath, c.Options.HashAlgorithm, fileInfo.Size > 1e7)
|
c.FilesToTransfer[i].Hash, err = utils.HashFile(fullPath, c.Options.HashAlgorithm, fileInfo.Size > 1e7)
|
||||||
log.Debugf("hashed %s to %x using %s", fullPath, c.FilesToTransfer[i].Hash, c.Options.HashAlgorithm)
|
log.Tracef("hashed %s to %x using %s", fullPath, c.FilesToTransfer[i].Hash, c.Options.HashAlgorithm)
|
||||||
totalFilesSize += fileInfo.Size
|
totalFilesSize += fileInfo.Size
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Debugf("file %d info: %+v", i, c.FilesToTransfer[i])
|
log.Tracef("file %d info: %+v", i, c.FilesToTransfer[i])
|
||||||
fmt.Fprintf(os.Stderr, "\r ")
|
fmt.Fprintf(os.Stderr, "\r ")
|
||||||
fmt.Fprintf(os.Stderr, "\rSending %d files (%s)", i, utils.ByteCountDecimal(totalFilesSize))
|
fmt.Fprintf(os.Stderr, "\rSending %d files (%s)", i, utils.ByteCountDecimal(totalFilesSize))
|
||||||
}
|
}
|
||||||
log.Debugf("longestFilename: %+v", c.longestFilename)
|
log.Tracef("longestFilename: %+v", c.longestFilename)
|
||||||
fname := fmt.Sprintf("%d files", len(c.FilesToTransfer))
|
fname := fmt.Sprintf("%d files", len(c.FilesToTransfer))
|
||||||
folderName := fmt.Sprintf("%d folders", c.TotalNumberFolders)
|
folderName := fmt.Sprintf("%d folders", c.TotalNumberFolders)
|
||||||
if len(c.FilesToTransfer) == 1 {
|
if len(c.FilesToTransfer) == 1 {
|
||||||
|
|
@ -595,42 +593,42 @@ func (c *Client) broadcastOnLocalNetwork(useipv6 bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
discoveries, err := peerdiscovery.Discover(settings)
|
discoveries, err := peerdiscovery.Discover(settings)
|
||||||
log.Debugf("discoveries: %+v", discoveries)
|
log.Tracef("discoveries: %+v", discoveries)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debug(err)
|
log.Trace(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) transferOverLocalRelay(errchan chan<- error) {
|
func (c *Client) transferOverLocalRelay(errchan chan<- error) {
|
||||||
time.Sleep(500 * time.Millisecond)
|
time.Sleep(500 * time.Millisecond)
|
||||||
log.Debug("establishing connection")
|
log.Trace("establishing connection")
|
||||||
var banner string
|
var banner string
|
||||||
conn, banner, ipaddr, err := tcp.ConnectToTCPServer("127.0.0.1:"+c.Options.RelayPorts[0], c.Options.RelayPassword, c.Options.RoomName)
|
conn, banner, ipaddr, err := tcp.ConnectToTCPServer("127.0.0.1:"+c.Options.RelayPorts[0], c.Options.RelayPassword, c.Options.RoomName)
|
||||||
log.Debugf("banner: %s", banner)
|
log.Tracef("banner: %s", banner)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = fmt.Errorf("could not connect to 127.0.0.1:%s: %w", c.Options.RelayPorts[0], err)
|
err = fmt.Errorf("could not connect to 127.0.0.1:%s: %w", c.Options.RelayPorts[0], err)
|
||||||
log.Debug(err)
|
log.Trace(err)
|
||||||
// not really an error because it will try to connect over the actual relay
|
// not really an error because it will try to connect over the actual relay
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Debugf("local connection established: %+v", conn)
|
log.Tracef("local connection established: %+v", conn)
|
||||||
for {
|
for {
|
||||||
data, _ := conn.Receive()
|
data, _ := conn.Receive()
|
||||||
if bytes.Equal(data, handshakeRequest) {
|
if bytes.Equal(data, handshakeRequest) {
|
||||||
break
|
break
|
||||||
} else if bytes.Equal(data, []byte{1}) {
|
} else if bytes.Equal(data, []byte{1}) {
|
||||||
log.Debug("got ping")
|
log.Trace("got ping")
|
||||||
} else {
|
} else {
|
||||||
log.Debugf("instead of handshake got: %s", data)
|
log.Tracef("instead of handshake got: %s", data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c.conn[0] = conn
|
c.conn[0] = conn
|
||||||
log.Debug("exchanged header message")
|
log.Trace("exchanged header message")
|
||||||
c.Options.RelayAddress = "127.0.0.1"
|
c.Options.RelayAddress = "127.0.0.1"
|
||||||
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.Trace("no multiplexing")
|
||||||
c.Options.RelayPorts = []string{c.Options.RelayPorts[0]}
|
c.Options.RelayPorts = []string{c.Options.RelayPorts[0]}
|
||||||
}
|
}
|
||||||
c.ExternalIP = ipaddr
|
c.ExternalIP = ipaddr
|
||||||
|
|
@ -662,9 +660,6 @@ On the other computer run:
|
||||||
CROC_SECRET=%[1]q croc %[2]s
|
CROC_SECRET=%[1]q croc %[2]s
|
||||||
`, c.Options.SharedSecret, flags.String())
|
`, c.Options.SharedSecret, flags.String())
|
||||||
copyToClipboard(c.Options.SharedSecret)
|
copyToClipboard(c.Options.SharedSecret)
|
||||||
if c.Options.ShowQrCode {
|
|
||||||
showReceiveCommandQrCode(fmt.Sprintf("%[1]s", c.Options.SharedSecret))
|
|
||||||
}
|
|
||||||
if c.Options.Ask {
|
if c.Options.Ask {
|
||||||
machid, _ := machineid.ID()
|
machid, _ := machineid.ID()
|
||||||
fmt.Fprintf(os.Stderr, "\rYour machine ID is '%s'\n", machid)
|
fmt.Fprintf(os.Stderr, "\rYour machine ID is '%s'\n", machid)
|
||||||
|
|
@ -696,33 +691,33 @@ On the other computer run:
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
host, port, _ := net.SplitHostPort(address)
|
host, port, _ := net.SplitHostPort(address)
|
||||||
log.Debugf("host: '%s', port: '%s'", host, port)
|
log.Tracef("host: '%s', port: '%s'", host, port)
|
||||||
// Default port to :9009
|
// Default port to :9009
|
||||||
if port == "" {
|
if port == "" {
|
||||||
host = address
|
host = address
|
||||||
port = models.DEFAULT_PORT
|
port = models.DEFAULT_PORT
|
||||||
}
|
}
|
||||||
log.Debugf("got host '%v' and port '%v'", host, port)
|
log.Tracef("got host '%v' and port '%v'", host, port)
|
||||||
address = net.JoinHostPort(host, port)
|
address = net.JoinHostPort(host, port)
|
||||||
log.Debugf("trying connection to %s", address)
|
log.Tracef("trying connection to %s", address)
|
||||||
conn, banner, ipaddr, err = tcp.ConnectToTCPServer(address, c.Options.RelayPassword, c.Options.RoomName, durations[i])
|
conn, banner, ipaddr, err = tcp.ConnectToTCPServer(address, c.Options.RelayPassword, c.Options.RoomName, durations[i])
|
||||||
if err == nil {
|
if err == nil {
|
||||||
c.Options.RelayAddress = address
|
c.Options.RelayAddress = address
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
log.Debugf("could not establish '%s'", address)
|
log.Tracef("could not establish '%s'", address)
|
||||||
}
|
}
|
||||||
if conn == nil && err == nil {
|
if conn == nil && err == nil {
|
||||||
err = fmt.Errorf("could not connect")
|
err = fmt.Errorf("could not connect")
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = fmt.Errorf("could not connect to %s: %w", c.Options.RelayAddress, err)
|
err = fmt.Errorf("could not connect to %s: %w", c.Options.RelayAddress, err)
|
||||||
log.Debug(err)
|
log.Trace(err)
|
||||||
errchan <- err
|
errchan <- err
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Debugf("banner: %s", banner)
|
log.Tracef("banner: %s", banner)
|
||||||
log.Debugf("connection established: %+v", conn)
|
log.Tracef("connection established: %+v", conn)
|
||||||
var kB []byte
|
var kB []byte
|
||||||
B, _ := pake.InitCurve([]byte(c.Options.SharedSecret[5:]), 1, c.Options.Curve)
|
B, _ := pake.InitCurve([]byte(c.Options.SharedSecret[5:]), 1, c.Options.Curve)
|
||||||
for {
|
for {
|
||||||
|
|
@ -809,11 +804,11 @@ On the other computer run:
|
||||||
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.Trace("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.Trace("exchanged header message")
|
||||||
errchan <- c.transfer()
|
errchan <- c.transfer()
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
@ -823,7 +818,7 @@ On the other computer run:
|
||||||
// return if no error
|
// return if no error
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
log.Debugf("error from errchan: %v", err)
|
log.Tracef("error from errchan: %v", err)
|
||||||
if strings.Contains(err.Error(), "could not secure channel") {
|
if strings.Contains(err.Error(), "could not secure channel") {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -837,13 +832,6 @@ On the other computer run:
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func showReceiveCommandQrCode(command string) {
|
|
||||||
qrCode, err := qrcode.New(command, qrcode.Medium)
|
|
||||||
if err == nil {
|
|
||||||
fmt.Println(qrCode.ToSmallString(false))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Receive will receive a file
|
// Receive will receive a file
|
||||||
func (c *Client) Receive() (err error) {
|
func (c *Client) Receive() (err error) {
|
||||||
fmt.Fprintf(os.Stderr, "connecting...")
|
fmt.Fprintf(os.Stderr, "connecting...")
|
||||||
|
|
@ -860,18 +848,18 @@ func (c *Client) Receive() (err error) {
|
||||||
if c.Options.IP != "" {
|
if c.Options.IP != "" {
|
||||||
// check ip version
|
// check ip version
|
||||||
if strings.Count(c.Options.IP, ":") >= 2 {
|
if strings.Count(c.Options.IP, ":") >= 2 {
|
||||||
log.Debug("assume ipv6")
|
log.Trace("assume ipv6")
|
||||||
c.Options.RelayAddress6 = c.Options.IP
|
c.Options.RelayAddress6 = c.Options.IP
|
||||||
}
|
}
|
||||||
if strings.Contains(c.Options.IP, ".") {
|
if strings.Contains(c.Options.IP, ".") {
|
||||||
log.Debug("assume ipv4")
|
log.Trace("assume ipv4")
|
||||||
c.Options.RelayAddress = c.Options.IP
|
c.Options.RelayAddress = c.Options.IP
|
||||||
}
|
}
|
||||||
isIPset = true
|
isIPset = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if !c.Options.DisableLocal && !isIPset {
|
if !c.Options.DisableLocal && !isIPset {
|
||||||
log.Debug("attempt to discover peers")
|
log.Trace("attempt to discover peers")
|
||||||
var discoveries []peerdiscovery.Discovered
|
var discoveries []peerdiscovery.Discovered
|
||||||
var wgDiscovery sync.WaitGroup
|
var wgDiscovery sync.WaitGroup
|
||||||
var dmux sync.Mutex
|
var dmux sync.Mutex
|
||||||
|
|
@ -911,14 +899,14 @@ func (c *Client) Receive() (err error) {
|
||||||
wgDiscovery.Wait()
|
wgDiscovery.Wait()
|
||||||
|
|
||||||
if err == nil && len(discoveries) > 0 {
|
if err == nil && len(discoveries) > 0 {
|
||||||
log.Debugf("all discoveries: %+v", discoveries)
|
log.Tracef("all discoveries: %+v", discoveries)
|
||||||
for i := 0; i < len(discoveries); i++ {
|
for i := 0; i < len(discoveries); i++ {
|
||||||
log.Debugf("discovery %d has payload: %+v", i, discoveries[i])
|
log.Tracef("discovery %d has payload: %+v", i, discoveries[i])
|
||||||
if !bytes.HasPrefix(discoveries[i].Payload, []byte("croc")) {
|
if !bytes.HasPrefix(discoveries[i].Payload, []byte("croc")) {
|
||||||
log.Debug("skipping discovery")
|
log.Trace("skipping discovery")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
log.Debug("switching to local")
|
log.Trace("switching to local")
|
||||||
portToUse := string(bytes.TrimPrefix(discoveries[i].Payload, []byte("croc")))
|
portToUse := string(bytes.TrimPrefix(discoveries[i].Payload, []byte("croc")))
|
||||||
if portToUse == "" {
|
if portToUse == "" {
|
||||||
portToUse = models.DEFAULT_PORT
|
portToUse = models.DEFAULT_PORT
|
||||||
|
|
@ -926,19 +914,19 @@ func (c *Client) Receive() (err error) {
|
||||||
address := net.JoinHostPort(discoveries[i].Address, portToUse)
|
address := net.JoinHostPort(discoveries[i].Address, portToUse)
|
||||||
errPing := tcp.PingServer(address)
|
errPing := tcp.PingServer(address)
|
||||||
if errPing == nil {
|
if errPing == nil {
|
||||||
log.Debugf("successfully pinged '%s'", address)
|
log.Tracef("successfully pinged '%s'", address)
|
||||||
c.Options.RelayAddress = address
|
c.Options.RelayAddress = address
|
||||||
c.ExternalIPConnected = c.Options.RelayAddress
|
c.ExternalIPConnected = c.Options.RelayAddress
|
||||||
c.Options.RelayAddress6 = ""
|
c.Options.RelayAddress6 = ""
|
||||||
usingLocal = true
|
usingLocal = true
|
||||||
break
|
break
|
||||||
} else {
|
} else {
|
||||||
log.Debugf("could not ping: %+v", errPing)
|
log.Tracef("could not ping: %+v", errPing)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.Debugf("discoveries: %+v", discoveries)
|
log.Tracef("discoveries: %+v", discoveries)
|
||||||
log.Debug("establishing connection")
|
log.Trace("establishing connection")
|
||||||
}
|
}
|
||||||
var banner string
|
var banner string
|
||||||
durations := []time.Duration{200 * time.Millisecond, 5 * time.Second}
|
durations := []time.Duration{200 * time.Millisecond, 5 * time.Second}
|
||||||
|
|
@ -954,26 +942,26 @@ func (c *Client) Receive() (err error) {
|
||||||
host = address
|
host = address
|
||||||
port = models.DEFAULT_PORT
|
port = models.DEFAULT_PORT
|
||||||
}
|
}
|
||||||
log.Debugf("got host '%v' and port '%v'", host, port)
|
log.Tracef("got host '%v' and port '%v'", host, port)
|
||||||
address = net.JoinHostPort(host, port)
|
address = net.JoinHostPort(host, port)
|
||||||
log.Debugf("trying connection to %s", address)
|
log.Tracef("trying connection to %s", address)
|
||||||
c.conn[0], banner, c.ExternalIP, err = tcp.ConnectToTCPServer(address, c.Options.RelayPassword, c.Options.RoomName, durations[i])
|
c.conn[0], banner, c.ExternalIP, err = tcp.ConnectToTCPServer(address, c.Options.RelayPassword, c.Options.RoomName, durations[i])
|
||||||
if err == nil {
|
if err == nil {
|
||||||
c.Options.RelayAddress = address
|
c.Options.RelayAddress = address
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
log.Debugf("could not establish '%s'", address)
|
log.Tracef("could not establish '%s'", address)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = fmt.Errorf("could not connect to %s: %w", c.Options.RelayAddress, err)
|
err = fmt.Errorf("could not connect to %s: %w", c.Options.RelayAddress, err)
|
||||||
log.Debug(err)
|
log.Trace(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Debugf("receiver connection established: %+v", c.conn[0])
|
log.Tracef("receiver connection established: %+v", c.conn[0])
|
||||||
log.Debugf("banner: %s", banner)
|
log.Tracef("banner: %s", banner)
|
||||||
|
|
||||||
if c.Options.TestFlag {
|
if c.Options.TestFlag {
|
||||||
log.Debugf("TEST FLAG ENABLED, TESTING LOCAL IPS")
|
log.Tracef("TEST FLAG ENABLED, TESTING LOCAL IPS")
|
||||||
}
|
}
|
||||||
if c.Options.TestFlag || (!usingLocal && !c.Options.DisableLocal && !isIPset) {
|
if c.Options.TestFlag || (!usingLocal && !c.Options.DisableLocal && !isIPset) {
|
||||||
// ask the sender for their local ips and port
|
// ask the sender for their local ips and port
|
||||||
|
|
@ -1002,7 +990,7 @@ func (c *Client) Receive() (err error) {
|
||||||
}
|
}
|
||||||
err = json.Unmarshal(data, &dataMessage)
|
err = json.Unmarshal(data, &dataMessage)
|
||||||
if err != nil || dataMessage.Kind != "pake2" {
|
if err != nil || dataMessage.Kind != "pake2" {
|
||||||
log.Debugf("data: %s", data)
|
log.Tracef("data: %s", data)
|
||||||
return fmt.Errorf("dataMessage %s pake failed", ipRequest)
|
return fmt.Errorf("dataMessage %s pake failed", ipRequest)
|
||||||
}
|
}
|
||||||
err = A.Update(dataMessage.Bytes)
|
err = A.Update(dataMessage.Bytes)
|
||||||
|
|
@ -1014,14 +1002,14 @@ func (c *Client) Receive() (err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Debugf("dataMessage kA: %x", kA)
|
log.Tracef("dataMessage kA: %x", kA)
|
||||||
|
|
||||||
// secure ipRequest
|
// secure ipRequest
|
||||||
data, err = crypt.Encrypt([]byte(ipRequest), kA)
|
data, err = crypt.Encrypt([]byte(ipRequest), kA)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Debug("sending ips?")
|
log.Trace("sending ips?")
|
||||||
if err = c.conn[0].Send(data); err != nil {
|
if err = c.conn[0].Send(data); err != nil {
|
||||||
log.Errorf("ips send error: %v", err)
|
log.Errorf("ips send error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -1033,9 +1021,9 @@ func (c *Client) Receive() (err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Debugf("ips data: %s", data)
|
log.Tracef("ips data: %s", data)
|
||||||
if err = json.Unmarshal(data, &ips); err != nil {
|
if err = json.Unmarshal(data, &ips); err != nil {
|
||||||
log.Debugf("ips unmarshal error: %v", err)
|
log.Tracef("ips unmarshal error: %v", err)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}()
|
}()
|
||||||
|
|
@ -1045,32 +1033,32 @@ func (c *Client) Receive() (err error) {
|
||||||
ips = ips[1:]
|
ips = ips[1:]
|
||||||
for _, ip := range ips {
|
for _, ip := range ips {
|
||||||
ipv4Addr, ipv4Net, errNet := net.ParseCIDR(fmt.Sprintf("%s/24", ip))
|
ipv4Addr, ipv4Net, errNet := net.ParseCIDR(fmt.Sprintf("%s/24", ip))
|
||||||
log.Debugf("ipv4Add4: %+v, ipv4Net: %+v, err: %+v", ipv4Addr, ipv4Net, errNet)
|
log.Tracef("ipv4Add4: %+v, ipv4Net: %+v, err: %+v", ipv4Addr, ipv4Net, errNet)
|
||||||
localIps, _ := utils.GetLocalIPs()
|
localIps, _ := utils.GetLocalIPs()
|
||||||
haveLocalIP := false
|
haveLocalIP := false
|
||||||
for _, localIP := range localIps {
|
for _, localIP := range localIps {
|
||||||
localIPparsed := net.ParseIP(localIP)
|
localIPparsed := net.ParseIP(localIP)
|
||||||
log.Debugf("localIP: %+v, localIPparsed: %+v", localIP, localIPparsed)
|
log.Tracef("localIP: %+v, localIPparsed: %+v", localIP, localIPparsed)
|
||||||
if ipv4Net.Contains(localIPparsed) {
|
if ipv4Net.Contains(localIPparsed) {
|
||||||
haveLocalIP = true
|
haveLocalIP = true
|
||||||
log.Debugf("ip: %+v is a local IP", ip)
|
log.Tracef("ip: %+v is a local IP", ip)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !haveLocalIP {
|
if !haveLocalIP {
|
||||||
log.Debugf("%s is not a local IP, skipping", ip)
|
log.Tracef("%s is not a local IP, skipping", ip)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
serverTry := net.JoinHostPort(ip, port)
|
serverTry := net.JoinHostPort(ip, port)
|
||||||
conn, banner2, externalIP, errConn := tcp.ConnectToTCPServer(serverTry, c.Options.RelayPassword, c.Options.RoomName, 500*time.Millisecond)
|
conn, banner2, externalIP, errConn := tcp.ConnectToTCPServer(serverTry, c.Options.RelayPassword, c.Options.RoomName, 500*time.Millisecond)
|
||||||
if errConn != nil {
|
if errConn != nil {
|
||||||
log.Debug(errConn)
|
log.Trace(errConn)
|
||||||
log.Debugf("could not connect to " + serverTry)
|
log.Tracef("could not connect to " + serverTry)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
log.Debugf("local connection established to %s", serverTry)
|
log.Tracef("local connection established to %s", serverTry)
|
||||||
log.Debugf("banner: %s", banner2)
|
log.Tracef("banner: %s", banner2)
|
||||||
// reset to the local port
|
// reset to the local port
|
||||||
banner = banner2
|
banner = banner2
|
||||||
c.Options.RelayAddress = serverTry
|
c.Options.RelayAddress = serverTry
|
||||||
|
|
@ -1088,10 +1076,10 @@ func (c *Client) Receive() (err error) {
|
||||||
}
|
}
|
||||||
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.Trace("no multiplexing")
|
||||||
c.Options.RelayPorts = []string{c.Options.RelayPorts[0]}
|
c.Options.RelayPorts = []string{c.Options.RelayPorts[0]}
|
||||||
}
|
}
|
||||||
log.Debug("exchanged header message")
|
log.Trace("exchanged header message")
|
||||||
fmt.Fprintf(os.Stderr, "\rsecuring channel...")
|
fmt.Fprintf(os.Stderr, "\rsecuring channel...")
|
||||||
err = c.transfer()
|
err = c.transfer()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|
@ -1109,7 +1097,7 @@ func (c *Client) transfer() (err error) {
|
||||||
c.quit = make(chan bool)
|
c.quit = make(chan bool)
|
||||||
|
|
||||||
// if recipient, initialize with sending pake information
|
// if recipient, initialize with sending pake information
|
||||||
log.Debug("ready")
|
log.Trace("ready")
|
||||||
if !c.Options.IsSender && !c.Step1ChannelSecured {
|
if !c.Options.IsSender && !c.Step1ChannelSecured {
|
||||||
err = message.Send(c.conn[0], c.Key, message.Message{
|
err = message.Send(c.conn[0], c.Key, message.Message{
|
||||||
Type: message.TypePAKE,
|
Type: message.TypePAKE,
|
||||||
|
|
@ -1127,7 +1115,7 @@ func (c *Client) transfer() (err error) {
|
||||||
var done bool
|
var done bool
|
||||||
data, err = c.conn[0].Receive()
|
data, err = c.conn[0].Receive()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debugf("got error receiving: %v", err)
|
log.Tracef("got error receiving: %v", err)
|
||||||
if !c.Step1ChannelSecured {
|
if !c.Step1ChannelSecured {
|
||||||
err = fmt.Errorf("could not secure channel")
|
err = fmt.Errorf("could not secure channel")
|
||||||
}
|
}
|
||||||
|
|
@ -1135,8 +1123,8 @@ func (c *Client) transfer() (err error) {
|
||||||
}
|
}
|
||||||
done, err = c.processMessage(data)
|
done, err = c.processMessage(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debugf("data: %s", data)
|
log.Tracef("data: %s", data)
|
||||||
log.Debugf("got error processing: %v", err)
|
log.Tracef("got error processing: %v", err)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if done {
|
if done {
|
||||||
|
|
@ -1146,7 +1134,7 @@ func (c *Client) transfer() (err error) {
|
||||||
// purge errors that come from successful transfer
|
// purge errors that come from successful transfer
|
||||||
if c.SuccessfulTransfer {
|
if c.SuccessfulTransfer {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debugf("purging error: %s", err)
|
log.Tracef("purging error: %s", err)
|
||||||
}
|
}
|
||||||
err = nil
|
err = nil
|
||||||
}
|
}
|
||||||
|
|
@ -1164,7 +1152,7 @@ func (c *Client) transfer() (err error) {
|
||||||
if file.TempFile {
|
if file.TempFile {
|
||||||
utils.UnzipDirectory(".", file.Name)
|
utils.UnzipDirectory(".", file.Name)
|
||||||
os.Remove(file.Name)
|
os.Remove(file.Name)
|
||||||
log.Debugf("Removing %s\n", file.Name)
|
log.Tracef("Removing %s\n", file.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1174,7 +1162,7 @@ func (c *Client) transfer() (err error) {
|
||||||
c.FilesToTransfer[c.FilesToTransferCurrentNum].FolderRemote,
|
c.FilesToTransfer[c.FilesToTransferCurrentNum].FolderRemote,
|
||||||
c.FilesToTransfer[c.FilesToTransferCurrentNum].Name,
|
c.FilesToTransfer[c.FilesToTransferCurrentNum].Name,
|
||||||
)
|
)
|
||||||
log.Debugf("pathToFile: %s", pathToFile)
|
log.Tracef("pathToFile: %s", pathToFile)
|
||||||
// close if not closed already
|
// close if not closed already
|
||||||
if !c.CurrentFileIsClosed {
|
if !c.CurrentFileIsClosed {
|
||||||
c.CurrentFile.Close()
|
c.CurrentFile.Close()
|
||||||
|
|
@ -1186,11 +1174,11 @@ func (c *Client) transfer() (err error) {
|
||||||
fmt.Fprint(os.Stderr, "\n")
|
fmt.Fprint(os.Stderr, "\n")
|
||||||
}
|
}
|
||||||
if err != nil && strings.Contains(err.Error(), "pake not successful") {
|
if err != nil && strings.Contains(err.Error(), "pake not successful") {
|
||||||
log.Debugf("pake error: %s", err.Error())
|
log.Tracef("pake error: %s", err.Error())
|
||||||
err = fmt.Errorf("password mismatch")
|
err = fmt.Errorf("password mismatch")
|
||||||
}
|
}
|
||||||
if err != nil && strings.Contains(err.Error(), "unexpected end of JSON input") {
|
if err != nil && strings.Contains(err.Error(), "unexpected end of JSON input") {
|
||||||
log.Debugf("error: %s", err.Error())
|
log.Tracef("error: %s", err.Error())
|
||||||
err = fmt.Errorf("room (secure channel) not ready, maybe peer disconnected")
|
err = fmt.Errorf("room (secure channel) not ready, maybe peer disconnected")
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
|
@ -1222,7 +1210,7 @@ func (c *Client) processMessageFileInfo(m message.Message) (done bool, err error
|
||||||
var senderInfo SenderInfo
|
var senderInfo SenderInfo
|
||||||
err = json.Unmarshal(m.Bytes, &senderInfo)
|
err = json.Unmarshal(m.Bytes, &senderInfo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debug(err)
|
log.Trace(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.Options.SendingText = senderInfo.SendingText
|
c.Options.SendingText = senderInfo.SendingText
|
||||||
|
|
@ -1267,9 +1255,9 @@ func (c *Client) processMessageFileInfo(m message.Message) (done bool, err error
|
||||||
if c.Options.HashAlgorithm == "" {
|
if c.Options.HashAlgorithm == "" {
|
||||||
c.Options.HashAlgorithm = "xxhash"
|
c.Options.HashAlgorithm = "xxhash"
|
||||||
}
|
}
|
||||||
log.Debugf("using hash algorithm: %s", c.Options.HashAlgorithm)
|
log.Tracef("using hash algorithm: %s", c.Options.HashAlgorithm)
|
||||||
if c.Options.NoCompress {
|
if c.Options.NoCompress {
|
||||||
log.Debug("disabling compression")
|
log.Trace("disabling compression")
|
||||||
}
|
}
|
||||||
if c.Options.SendingText {
|
if c.Options.SendingText {
|
||||||
c.Options.Stdout = true
|
c.Options.Stdout = true
|
||||||
|
|
@ -1342,7 +1330,7 @@ func (c *Client) processMessageFileInfo(m message.Message) (done bool, err error
|
||||||
} else {
|
} else {
|
||||||
isEmpty, _ := isEmptyFolder(c.EmptyFoldersToTransfer[i].FolderRemote)
|
isEmpty, _ := isEmptyFolder(c.EmptyFoldersToTransfer[i].FolderRemote)
|
||||||
if !isEmpty {
|
if !isEmpty {
|
||||||
log.Debug("asking to overwrite")
|
log.Trace("asking to overwrite")
|
||||||
prompt := fmt.Sprintf("\n%s already has some content in it. \nDo you want"+
|
prompt := fmt.Sprintf("\n%s already has some content in it. \nDo you want"+
|
||||||
" to overwrite it with an empty folder? (y/N) ", c.EmptyFoldersToTransfer[i].FolderRemote)
|
" to overwrite it with an empty folder? (y/N) ", c.EmptyFoldersToTransfer[i].FolderRemote)
|
||||||
choice := strings.ToLower(utils.GetInput(prompt))
|
choice := strings.ToLower(utils.GetInput(prompt))
|
||||||
|
|
@ -1368,18 +1356,18 @@ func (c *Client) processMessageFileInfo(m message.Message) (done bool, err error
|
||||||
err = errStopTransfer
|
err = errStopTransfer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.Debug(c.FilesToTransfer)
|
log.Trace(c.FilesToTransfer)
|
||||||
c.Step2FileInfoTransferred = true
|
c.Step2FileInfoTransferred = true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) processMessagePake(m message.Message) (err error) {
|
func (c *Client) processMessagePake(m message.Message) (err error) {
|
||||||
log.Debug("received pake payload")
|
log.Trace("received pake payload")
|
||||||
|
|
||||||
var salt []byte
|
var salt []byte
|
||||||
if c.Options.IsSender {
|
if c.Options.IsSender {
|
||||||
// initialize curve based on the recipient's choice
|
// initialize curve based on the recipient's choice
|
||||||
log.Debugf("using curve %s", string(m.Bytes2))
|
log.Tracef("using curve %s", string(m.Bytes2))
|
||||||
c.Pake, err = pake.InitCurve([]byte(c.Options.SharedSecret[5:]), 1, string(m.Bytes2))
|
c.Pake, err = pake.InitCurve([]byte(c.Options.SharedSecret[5:]), 1, string(m.Bytes2))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
|
|
@ -1393,13 +1381,13 @@ func (c *Client) processMessagePake(m message.Message) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate salt and send it back to recipient
|
// generate salt and send it back to recipient
|
||||||
log.Debug("generating salt")
|
log.Trace("generating salt")
|
||||||
salt = make([]byte, 8)
|
salt = make([]byte, 8)
|
||||||
if _, rerr := rand.Read(salt); err != nil {
|
if _, rerr := rand.Read(salt); err != nil {
|
||||||
log.Errorf("can't generate random numbers: %v", rerr)
|
log.Errorf("can't generate random numbers: %v", rerr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Debug("sender sending pake+salt")
|
log.Trace("sender sending pake+salt")
|
||||||
err = message.Send(c.conn[0], c.Key, message.Message{
|
err = message.Send(c.conn[0], c.Key, message.Message{
|
||||||
Type: message.TypePAKE,
|
Type: message.TypePAKE,
|
||||||
Bytes: c.Pake.Bytes(),
|
Bytes: c.Pake.Bytes(),
|
||||||
|
|
@ -1421,13 +1409,13 @@ func (c *Client) processMessagePake(m message.Message) (err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.Debugf("generated key = %+x with salt %x", c.Key, salt)
|
log.Tracef("generated key = %+x with salt %x", c.Key, salt)
|
||||||
|
|
||||||
// connects to the other ports of the server for transfer
|
// connects to the other ports of the server for transfer
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
wg.Add(len(c.Options.RelayPorts))
|
wg.Add(len(c.Options.RelayPorts))
|
||||||
for i := 0; i < len(c.Options.RelayPorts); i++ {
|
for i := 0; i < len(c.Options.RelayPorts); i++ {
|
||||||
log.Debugf("port: [%s]", c.Options.RelayPorts[i])
|
log.Tracef("port: [%s]", c.Options.RelayPorts[i])
|
||||||
go func(j int) {
|
go func(j int) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
var host string
|
var host string
|
||||||
|
|
@ -1441,7 +1429,7 @@ func (c *Client) processMessagePake(m message.Message) (err error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
server := net.JoinHostPort(host, c.Options.RelayPorts[j])
|
server := net.JoinHostPort(host, c.Options.RelayPorts[j])
|
||||||
log.Debugf("connecting to %s", server)
|
log.Tracef("connecting to %s", server)
|
||||||
c.conn[j+1], _, _, err = tcp.ConnectToTCPServer(
|
c.conn[j+1], _, _, err = tcp.ConnectToTCPServer(
|
||||||
server,
|
server,
|
||||||
c.Options.RelayPassword,
|
c.Options.RelayPassword,
|
||||||
|
|
@ -1450,7 +1438,7 @@ func (c *Client) processMessagePake(m message.Message) (err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
log.Debugf("connected to %s", server)
|
log.Tracef("connected to %s", server)
|
||||||
if !c.Options.IsSender {
|
if !c.Options.IsSender {
|
||||||
go c.receiveData(j)
|
go c.receiveData(j)
|
||||||
}
|
}
|
||||||
|
|
@ -1459,7 +1447,7 @@ func (c *Client) processMessagePake(m message.Message) (err error) {
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
|
||||||
if !c.Options.IsSender {
|
if !c.Options.IsSender {
|
||||||
log.Debug("sending external IP")
|
log.Trace("sending external IP")
|
||||||
err = message.Send(c.conn[0], c.Key, message.Message{
|
err = message.Send(c.conn[0], c.Key, message.Message{
|
||||||
Type: message.TypeExternalIP,
|
Type: message.TypeExternalIP,
|
||||||
Message: c.ExternalIP,
|
Message: c.ExternalIP,
|
||||||
|
|
@ -1470,7 +1458,7 @@ func (c *Client) processMessagePake(m message.Message) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) processExternalIP(m message.Message) (done bool, err error) {
|
func (c *Client) processExternalIP(m message.Message) (done bool, err error) {
|
||||||
log.Debugf("received external IP: %+v", m)
|
log.Tracef("received external IP: %+v", m)
|
||||||
if c.Options.IsSender {
|
if c.Options.IsSender {
|
||||||
err = message.Send(c.conn[0], c.Key, message.Message{
|
err = message.Send(c.conn[0], c.Key, message.Message{
|
||||||
Type: message.TypeExternalIP,
|
Type: message.TypeExternalIP,
|
||||||
|
|
@ -1484,7 +1472,7 @@ func (c *Client) processExternalIP(m message.Message) (done bool, err error) {
|
||||||
// it can be preset by the local relay
|
// it can be preset by the local relay
|
||||||
c.ExternalIPConnected = m.Message
|
c.ExternalIPConnected = m.Message
|
||||||
}
|
}
|
||||||
log.Debugf("connected as %s -> %s", c.ExternalIP, c.ExternalIPConnected)
|
log.Tracef("connected as %s -> %s", c.ExternalIP, c.ExternalIPConnected)
|
||||||
c.Step1ChannelSecured = true
|
c.Step1ChannelSecured = true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -1493,7 +1481,7 @@ func (c *Client) processMessage(payload []byte) (done bool, err error) {
|
||||||
m, err := message.Decode(c.Key, payload)
|
m, err := message.Decode(c.Key, payload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = fmt.Errorf("problem with decoding: %w", err)
|
err = fmt.Errorf("problem with decoding: %w", err)
|
||||||
log.Debug(err)
|
log.Trace(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1508,6 +1496,7 @@ func (c *Client) processMessage(payload []byte) (done bool, err error) {
|
||||||
|
|
||||||
switch m.Type {
|
switch m.Type {
|
||||||
case message.TypeFinished:
|
case message.TypeFinished:
|
||||||
|
log.Tracef("message.TypeFinished")
|
||||||
err = message.Send(c.conn[0], c.Key, message.Message{
|
err = message.Send(c.conn[0], c.Key, message.Message{
|
||||||
Type: message.TypeFinished,
|
Type: message.TypeFinished,
|
||||||
})
|
})
|
||||||
|
|
@ -1515,21 +1504,28 @@ func (c *Client) processMessage(payload []byte) (done bool, err error) {
|
||||||
c.SuccessfulTransfer = true
|
c.SuccessfulTransfer = true
|
||||||
return
|
return
|
||||||
case message.TypePAKE:
|
case message.TypePAKE:
|
||||||
|
log.Tracef("message.TypePAKE")
|
||||||
err = c.processMessagePake(m)
|
err = c.processMessagePake(m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = fmt.Errorf("pake not successful: %w", err)
|
err = fmt.Errorf("pake not successful: %w", err)
|
||||||
log.Debug(err)
|
log.Trace(err)
|
||||||
}
|
}
|
||||||
case message.TypeExternalIP:
|
case message.TypeExternalIP:
|
||||||
|
log.Tracef("message.TypeExternalIP")
|
||||||
done, err = c.processExternalIP(m)
|
done, err = c.processExternalIP(m)
|
||||||
case message.TypeError:
|
case message.TypeError:
|
||||||
|
log.Tracef("message.TypeError")
|
||||||
// c.spinner.Stop()
|
// c.spinner.Stop()
|
||||||
fmt.Print("\r")
|
fmt.Print("\r")
|
||||||
err = fmt.Errorf("peer error: %s", m.Message)
|
err = fmt.Errorf("peer error: %s", m.Message)
|
||||||
return true, err
|
return true, err
|
||||||
case message.TypeFileInfo:
|
case message.TypeFileInfo:
|
||||||
|
log.Tracef("message.TypeFileInfo")
|
||||||
done, err = c.processMessageFileInfo(m)
|
done, err = c.processMessageFileInfo(m)
|
||||||
case message.TypeRecipientReady:
|
case message.TypeRecipientReady:
|
||||||
|
log.Tracef("message.TypeRecipientReady")
|
||||||
|
c.Step4FileTransferred = false
|
||||||
|
c.Step3RecipientRequestFile = false
|
||||||
var remoteFile RemoteFileRequest
|
var remoteFile RemoteFileRequest
|
||||||
err = json.Unmarshal(m.Bytes, &remoteFile)
|
err = json.Unmarshal(m.Bytes, &remoteFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -1538,7 +1534,7 @@ func (c *Client) processMessage(payload []byte) (done bool, err error) {
|
||||||
c.FilesToTransferCurrentNum = remoteFile.FilesToTransferCurrentNum
|
c.FilesToTransferCurrentNum = remoteFile.FilesToTransferCurrentNum
|
||||||
c.CurrentFileChunkRanges = remoteFile.CurrentFileChunkRanges
|
c.CurrentFileChunkRanges = remoteFile.CurrentFileChunkRanges
|
||||||
c.CurrentFileChunks = utils.ChunkRangesToChunks(c.CurrentFileChunkRanges)
|
c.CurrentFileChunks = utils.ChunkRangesToChunks(c.CurrentFileChunkRanges)
|
||||||
log.Debugf("current file chunks: %+v", c.CurrentFileChunks)
|
log.Tracef("current file chunks: %+v", c.CurrentFileChunks)
|
||||||
c.mutex.Lock()
|
c.mutex.Lock()
|
||||||
c.chunkMap = make(map[uint64]struct{})
|
c.chunkMap = make(map[uint64]struct{})
|
||||||
for _, chunk := range c.CurrentFileChunks {
|
for _, chunk := range c.CurrentFileChunks {
|
||||||
|
|
@ -1560,25 +1556,27 @@ func (c *Client) processMessage(payload []byte) (done bool, err error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case message.TypeCloseSender:
|
case message.TypeCloseSender:
|
||||||
|
log.Tracef("message.TypeCloseSender")
|
||||||
c.bar.Finish()
|
c.bar.Finish()
|
||||||
log.Debug("close-sender received...")
|
log.Trace("close-sender received...")
|
||||||
c.Step4FileTransferred = false
|
c.Step4FileTransferred = false
|
||||||
c.Step3RecipientRequestFile = false
|
c.Step3RecipientRequestFile = false
|
||||||
log.Debug("sending close-recipient")
|
log.Trace("sending close-recipient")
|
||||||
err = message.Send(c.conn[0], c.Key, message.Message{
|
err = message.Send(c.conn[0], c.Key, message.Message{
|
||||||
Type: message.TypeCloseRecipient,
|
Type: message.TypeCloseRecipient,
|
||||||
})
|
})
|
||||||
case message.TypeCloseRecipient:
|
case message.TypeCloseRecipient:
|
||||||
|
log.Tracef("message.TypeCloseRecipient")
|
||||||
c.Step4FileTransferred = false
|
c.Step4FileTransferred = false
|
||||||
c.Step3RecipientRequestFile = false
|
c.Step3RecipientRequestFile = false
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debugf("got error from processing message: %v", err)
|
log.Tracef("got error from processing message: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = c.updateState()
|
err = c.updateState()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debugf("got error from updating state: %v", err)
|
log.Tracef("got error from updating state: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
|
@ -1617,7 +1615,7 @@ func (c *Client) updateIfSenderChannelSecured() (err error) {
|
||||||
|
|
||||||
func (c *Client) recipientInitializeFile() (err error) {
|
func (c *Client) recipientInitializeFile() (err error) {
|
||||||
// start initiating the process to receive a new file
|
// start initiating the process to receive a new file
|
||||||
log.Debugf("working on file %d", c.FilesToTransferCurrentNum)
|
log.Tracef("working on file %d", c.FilesToTransferCurrentNum)
|
||||||
|
|
||||||
// recipient sets the file
|
// recipient sets the file
|
||||||
pathToFile := path.Join(
|
pathToFile := path.Join(
|
||||||
|
|
@ -1677,7 +1675,7 @@ func (c *Client) recipientInitializeFile() (err error) {
|
||||||
func (c *Client) recipientGetFileReady(finished bool) (err error) {
|
func (c *Client) recipientGetFileReady(finished bool) (err error) {
|
||||||
if finished {
|
if finished {
|
||||||
// TODO: do the last finishing stuff
|
// TODO: do the last finishing stuff
|
||||||
log.Debug("finished")
|
log.Trace("finished")
|
||||||
err = message.Send(c.conn[0], c.Key, message.Message{
|
err = message.Send(c.conn[0], c.Key, message.Message{
|
||||||
Type: message.TypeFinished,
|
Type: message.TypeFinished,
|
||||||
})
|
})
|
||||||
|
|
@ -1688,7 +1686,7 @@ func (c *Client) recipientGetFileReady(finished bool) (err error) {
|
||||||
c.FilesHasFinished[c.FilesToTransferCurrentNum] = struct{}{}
|
c.FilesHasFinished[c.FilesToTransferCurrentNum] = struct{}{}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
log.Tracef("recipientGetFileReady: recipientInitializeFile")
|
||||||
err = c.recipientInitializeFile()
|
err = c.recipientInitializeFile()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
|
@ -1702,7 +1700,7 @@ func (c *Client) recipientGetFileReady(finished bool) (err error) {
|
||||||
FilesToTransferCurrentNum: c.FilesToTransferCurrentNum,
|
FilesToTransferCurrentNum: c.FilesToTransferCurrentNum,
|
||||||
MachineID: machID,
|
MachineID: machID,
|
||||||
})
|
})
|
||||||
log.Debug("converting to chunk range")
|
log.Tracef("utils.ChunkRangesToChunks(c.CurrentFileChunkRanges)")
|
||||||
c.CurrentFileChunks = utils.ChunkRangesToChunks(c.CurrentFileChunkRanges)
|
c.CurrentFileChunks = utils.ChunkRangesToChunks(c.CurrentFileChunkRanges)
|
||||||
|
|
||||||
if !finished {
|
if !finished {
|
||||||
|
|
@ -1710,7 +1708,7 @@ func (c *Client) recipientGetFileReady(finished bool) (err error) {
|
||||||
c.setBar()
|
c.setBar()
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("sending recipient ready with %d chunks", len(c.CurrentFileChunks))
|
log.Tracef("sending recipient ready with %d chunks", len(c.CurrentFileChunks))
|
||||||
err = message.Send(c.conn[0], c.Key, message.Message{
|
err = message.Send(c.conn[0], c.Key, message.Message{
|
||||||
Type: message.TypeRecipientReady,
|
Type: message.TypeRecipientReady,
|
||||||
Bytes: bRequest,
|
Bytes: bRequest,
|
||||||
|
|
@ -1742,7 +1740,7 @@ func formatDescription(description string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) createEmptyFileAndFinish(fileInfo FileInfo, i int) (err error) {
|
func (c *Client) createEmptyFileAndFinish(fileInfo FileInfo, i int) (err error) {
|
||||||
log.Debugf("touching file with folder / name")
|
log.Tracef("touching file with folder / name")
|
||||||
if !utils.Exists(fileInfo.FolderRemote) {
|
if !utils.Exists(fileInfo.FolderRemote) {
|
||||||
err = os.MkdirAll(fileInfo.FolderRemote, os.ModePerm)
|
err = os.MkdirAll(fileInfo.FolderRemote, os.ModePerm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -1752,7 +1750,7 @@ func (c *Client) createEmptyFileAndFinish(fileInfo FileInfo, i int) (err error)
|
||||||
}
|
}
|
||||||
pathToFile := path.Join(fileInfo.FolderRemote, fileInfo.Name)
|
pathToFile := path.Join(fileInfo.FolderRemote, fileInfo.Name)
|
||||||
if fileInfo.Symlink != "" {
|
if fileInfo.Symlink != "" {
|
||||||
log.Debug("creating symlink")
|
log.Trace("creating symlink")
|
||||||
// remove symlink if it exists
|
// remove symlink if it exists
|
||||||
if _, errExists := os.Lstat(pathToFile); errExists == nil {
|
if _, errExists := os.Lstat(pathToFile); errExists == nil {
|
||||||
os.Remove(pathToFile)
|
os.Remove(pathToFile)
|
||||||
|
|
@ -1808,7 +1806,7 @@ func (c *Client) updateIfRecipientHasFileInfo() (err error) {
|
||||||
if i < c.FilesToTransferCurrentNum {
|
if i < c.FilesToTransferCurrentNum {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
log.Debugf("checking %+v", fileInfo)
|
log.Tracef("checking %+v", fileInfo)
|
||||||
recipientFileInfo, errRecipientFile := os.Lstat(path.Join(fileInfo.FolderRemote, fileInfo.Name))
|
recipientFileInfo, errRecipientFile := os.Lstat(path.Join(fileInfo.FolderRemote, fileInfo.Name))
|
||||||
var errHash error
|
var errHash error
|
||||||
var fileHash []byte
|
var fileHash []byte
|
||||||
|
|
@ -1825,10 +1823,10 @@ func (c *Client) updateIfRecipientHasFileInfo() (err error) {
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
log.Debugf("%s %+x %+x %+v", fileInfo.Name, fileHash, fileInfo.Hash, errHash)
|
log.Tracef("%s %+x %+x %+v", fileInfo.Name, fileHash, fileInfo.Hash, errHash)
|
||||||
if !bytes.Equal(fileHash, fileInfo.Hash) {
|
if !bytes.Equal(fileHash, fileInfo.Hash) {
|
||||||
log.Debugf("hashed %s to %x using %s", fileInfo.Name, fileHash, c.Options.HashAlgorithm)
|
log.Tracef("hashed %s to %x using %s", fileInfo.Name, fileHash, c.Options.HashAlgorithm)
|
||||||
log.Debugf("hashes are not equal %x != %x", fileHash, fileInfo.Hash)
|
log.Tracef("hashes are not equal %x != %x", fileHash, fileInfo.Hash)
|
||||||
if errHash == nil && !c.Options.Overwrite && errRecipientFile == nil && !strings.HasPrefix(fileInfo.Name, "croc-stdin-") && !c.Options.SendingText {
|
if errHash == nil && !c.Options.Overwrite && errRecipientFile == nil && !strings.HasPrefix(fileInfo.Name, "croc-stdin-") && !c.Options.SendingText {
|
||||||
|
|
||||||
missingChunks := utils.ChunkRangesToChunks(utils.MissingChunks(
|
missingChunks := utils.ChunkRangesToChunks(utils.MissingChunks(
|
||||||
|
|
@ -1838,7 +1836,7 @@ func (c *Client) updateIfRecipientHasFileInfo() (err error) {
|
||||||
))
|
))
|
||||||
percentDone := 100 - float64(len(missingChunks)*models.TCP_BUFFER_SIZE/2)/float64(fileInfo.Size)*100
|
percentDone := 100 - float64(len(missingChunks)*models.TCP_BUFFER_SIZE/2)/float64(fileInfo.Size)*100
|
||||||
|
|
||||||
log.Debug("asking to overwrite")
|
log.Trace("asking to overwrite")
|
||||||
prompt := fmt.Sprintf("\nOverwrite '%s'? (y/N) (use --overwrite to omit) ", path.Join(fileInfo.FolderRemote, fileInfo.Name))
|
prompt := fmt.Sprintf("\nOverwrite '%s'? (y/N) (use --overwrite to omit) ", path.Join(fileInfo.FolderRemote, fileInfo.Name))
|
||||||
if percentDone < 99 {
|
if percentDone < 99 {
|
||||||
prompt = fmt.Sprintf("\nResume '%s' (%2.1f%%)? (y/N) (use --overwrite to omit) ", path.Join(fileInfo.FolderRemote, fileInfo.Name), percentDone)
|
prompt = fmt.Sprintf("\nResume '%s' (%2.1f%%)? (y/N) (use --overwrite to omit) ", path.Join(fileInfo.FolderRemote, fileInfo.Name), percentDone)
|
||||||
|
|
@ -1850,11 +1848,11 @@ func (c *Client) updateIfRecipientHasFileInfo() (err error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Debugf("hashes are equal %x == %x", fileHash, fileInfo.Hash)
|
log.Tracef("hashes are equal %x == %x", fileHash, fileInfo.Hash)
|
||||||
}
|
}
|
||||||
if errHash != nil {
|
if errHash != nil {
|
||||||
// probably can't find, its okay
|
// probably can't find, its okay
|
||||||
log.Debug(errHash)
|
log.Trace(errHash)
|
||||||
}
|
}
|
||||||
if errHash != nil || !bytes.Equal(fileHash, fileInfo.Hash) {
|
if errHash != nil || !bytes.Equal(fileHash, fileInfo.Hash) {
|
||||||
finished = false
|
finished = false
|
||||||
|
|
@ -1893,7 +1891,7 @@ func (c *Client) updateState() (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.Options.IsSender && c.Step3RecipientRequestFile && !c.Step4FileTransferred {
|
if c.Options.IsSender && c.Step3RecipientRequestFile && !c.Step4FileTransferred {
|
||||||
log.Debug("start sending data!")
|
log.Trace("start sending data!")
|
||||||
|
|
||||||
if !c.firstSend {
|
if !c.firstSend {
|
||||||
fmt.Fprintf(os.Stderr, "\nSending (->%s)\n", c.ExternalIPConnected)
|
fmt.Fprintf(os.Stderr, "\nSending (->%s)\n", c.ExternalIPConnected)
|
||||||
|
|
@ -1929,7 +1927,7 @@ func (c *Client) updateState() (err error) {
|
||||||
c.setBar()
|
c.setBar()
|
||||||
c.TotalSent = 0
|
c.TotalSent = 0
|
||||||
c.CurrentFileIsClosed = false
|
c.CurrentFileIsClosed = false
|
||||||
log.Debug("beginning sending comms")
|
log.Trace("beginning sending comms")
|
||||||
pathToFile := path.Join(
|
pathToFile := path.Join(
|
||||||
c.FilesToTransfer[c.FilesToTransferCurrentNum].FolderSource,
|
c.FilesToTransfer[c.FilesToTransferCurrentNum].FolderSource,
|
||||||
c.FilesToTransfer[c.FilesToTransferCurrentNum].Name,
|
c.FilesToTransfer[c.FilesToTransferCurrentNum].Name,
|
||||||
|
|
@ -1940,7 +1938,7 @@ func (c *Client) updateState() (err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for i := 0; i < len(c.Options.RelayPorts); i++ {
|
for i := 0; i < len(c.Options.RelayPorts); i++ {
|
||||||
log.Debugf("starting sending over comm %d", i)
|
log.Tracef("starting sending over comm %d", i)
|
||||||
go c.sendData(i)
|
go c.sendData(i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1972,9 +1970,9 @@ func (c *Client) setBar() {
|
||||||
byteToDo := int64(len(c.CurrentFileChunks) * models.TCP_BUFFER_SIZE / 2)
|
byteToDo := int64(len(c.CurrentFileChunks) * models.TCP_BUFFER_SIZE / 2)
|
||||||
if byteToDo > 0 {
|
if byteToDo > 0 {
|
||||||
bytesDone := c.FilesToTransfer[c.FilesToTransferCurrentNum].Size - byteToDo
|
bytesDone := c.FilesToTransfer[c.FilesToTransferCurrentNum].Size - byteToDo
|
||||||
log.Debug(byteToDo)
|
log.Trace(byteToDo)
|
||||||
log.Debug(c.FilesToTransfer[c.FilesToTransferCurrentNum].Size)
|
log.Trace(c.FilesToTransfer[c.FilesToTransferCurrentNum].Size)
|
||||||
log.Debug(bytesDone)
|
log.Trace(bytesDone)
|
||||||
if bytesDone > 0 {
|
if bytesDone > 0 {
|
||||||
c.bar.Add64(bytesDone)
|
c.bar.Add64(bytesDone)
|
||||||
}
|
}
|
||||||
|
|
@ -2018,15 +2016,15 @@ func (c *Client) receiveData(i int) {
|
||||||
c.bar.Add(len(data[8:]))
|
c.bar.Add(len(data[8:]))
|
||||||
c.TotalSent += int64(len(data[8:]))
|
c.TotalSent += int64(len(data[8:]))
|
||||||
c.TotalChunksTransferred++
|
c.TotalChunksTransferred++
|
||||||
// log.Debug(len(c.CurrentFileChunks), c.TotalChunksTransferred, c.TotalSent, c.FilesToTransfer[c.FilesToTransferCurrentNum].Size)
|
// log.Trace(len(c.CurrentFileChunks), c.TotalChunksTransferred, c.TotalSent, c.FilesToTransfer[c.FilesToTransferCurrentNum].Size)
|
||||||
|
|
||||||
if !c.CurrentFileIsClosed && (c.TotalChunksTransferred == len(c.CurrentFileChunks) || c.TotalSent == c.FilesToTransfer[c.FilesToTransferCurrentNum].Size) {
|
if !c.CurrentFileIsClosed && (c.TotalChunksTransferred == len(c.CurrentFileChunks) || c.TotalSent == c.FilesToTransfer[c.FilesToTransferCurrentNum].Size) {
|
||||||
c.CurrentFileIsClosed = true
|
c.CurrentFileIsClosed = true
|
||||||
log.Debug("finished receiving!")
|
log.Trace("finished receiving!")
|
||||||
if err = c.CurrentFile.Close(); err != nil {
|
if err = c.CurrentFile.Close(); err != nil {
|
||||||
log.Debugf("error closing %s: %v", c.CurrentFile.Name(), err)
|
log.Tracef("error closing %s: %v", c.CurrentFile.Name(), err)
|
||||||
} else {
|
} else {
|
||||||
log.Debugf("Successful closing %s", c.CurrentFile.Name())
|
log.Tracef("Successful closing %s", c.CurrentFile.Name())
|
||||||
}
|
}
|
||||||
if c.Options.Stdout || c.Options.SendingText {
|
if c.Options.Stdout || c.Options.SendingText {
|
||||||
pathToFile := path.Join(
|
pathToFile := path.Join(
|
||||||
|
|
@ -2036,13 +2034,15 @@ func (c *Client) receiveData(i int) {
|
||||||
b, _ := os.ReadFile(pathToFile)
|
b, _ := os.ReadFile(pathToFile)
|
||||||
fmt.Print(string(b))
|
fmt.Print(string(b))
|
||||||
}
|
}
|
||||||
log.Debug("sending close-sender")
|
log.Trace("sending close-sender")
|
||||||
err = message.Send(c.conn[0], c.Key, message.Message{
|
err = message.Send(c.conn[0], c.Key, message.Message{
|
||||||
Type: message.TypeCloseSender,
|
Type: message.TypeRecipientReady,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
c.Step4FileTransferred = false
|
||||||
|
c.Step3RecipientRequestFile = false
|
||||||
}
|
}
|
||||||
c.mutex.Unlock()
|
c.mutex.Unlock()
|
||||||
}
|
}
|
||||||
|
|
@ -2050,10 +2050,10 @@ func (c *Client) receiveData(i int) {
|
||||||
|
|
||||||
func (c *Client) sendData(i int) {
|
func (c *Client) sendData(i int) {
|
||||||
defer func() {
|
defer func() {
|
||||||
log.Debugf("finished with %d", i)
|
log.Tracef("finished with %d", i)
|
||||||
c.numfinished++
|
c.numfinished++
|
||||||
if c.numfinished == len(c.Options.RelayPorts) {
|
if c.numfinished == len(c.Options.RelayPorts) {
|
||||||
log.Debug("closing file")
|
log.Trace("closing file")
|
||||||
if err := c.fread.Close(); err != nil {
|
if err := c.fread.Close(); err != nil {
|
||||||
log.Errorf("error closing file: %v", err)
|
log.Errorf("error closing file: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -2072,7 +2072,7 @@ func (c *Client) sendData(i int) {
|
||||||
n, errRead = c.fread.ReadAt(data, readingPos)
|
n, errRead = c.fread.ReadAt(data, readingPos)
|
||||||
if c.limiter != nil {
|
if c.limiter != nil {
|
||||||
r := c.limiter.ReserveN(time.Now(), n)
|
r := c.limiter.ReserveN(time.Now(), n)
|
||||||
log.Debugf("Limiting Upload for %d", r.Delay())
|
log.Tracef("Limiting Upload for %d", r.Delay())
|
||||||
time.Sleep(r.Delay())
|
time.Sleep(r.Delay())
|
||||||
}
|
}
|
||||||
if n > 0 {
|
if n > 0 {
|
||||||
|
|
@ -2088,7 +2088,7 @@ func (c *Client) sendData(i int) {
|
||||||
}
|
}
|
||||||
c.mutex.Unlock()
|
c.mutex.Unlock()
|
||||||
if usableChunk {
|
if usableChunk {
|
||||||
// log.Debugf("sending chunk %d", pos)
|
// log.Tracef("sending chunk %d", pos)
|
||||||
posByte := make([]byte, 8)
|
posByte := make([]byte, 8)
|
||||||
binary.LittleEndian.PutUint64(posByte, pos)
|
binary.LittleEndian.PutUint64(posByte, pos)
|
||||||
var err error
|
var err error
|
||||||
|
|
@ -2155,8 +2155,8 @@ func copyToClipboard(str string) {
|
||||||
}
|
}
|
||||||
cmd.Stdin = bytes.NewReader([]byte(str))
|
cmd.Stdin = bytes.NewReader([]byte(str))
|
||||||
if err := cmd.Run(); err != nil {
|
if err := cmd.Run(); err != nil {
|
||||||
log.Debugf("error copying to clipboard: %v", err)
|
log.Tracef("error copying to clipboard: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fmt.Fprintf(os.Stderr, "Code copied to clipboard\n")
|
fmt.Fprintf(os.Stderr, "Code copied to clipboard")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ type DiskUsage struct {
|
||||||
stat *unix.Statfs_t
|
stat *unix.Statfs_t
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDiskUsage returns an object holding the disk usage of volumePath
|
// NewDiskUsages returns an object holding the disk usage of volumePath
|
||||||
// or nil in case of error (invalid path, etc)
|
// or nil in case of error (invalid path, etc)
|
||||||
func NewDiskUsage(volumePath string) *DiskUsage {
|
func NewDiskUsage(volumePath string) *DiskUsage {
|
||||||
stat := unix.Statfs_t{}
|
stat := unix.Statfs_t{}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ type DiskUsage struct {
|
||||||
availBytes int64
|
availBytes int64
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDiskUsage returns an object holding the disk usage of volumePath
|
// NewDiskUsages returns an object holding the disk usage of volumePath
|
||||||
// or nil in case of error (invalid path, etc)
|
// or nil in case of error (invalid path, etc)
|
||||||
func NewDiskUsage(volumePath string) *DiskUsage {
|
func NewDiskUsage(volumePath string) *DiskUsage {
|
||||||
h := windows.MustLoadDLL("kernel32.dll")
|
h := windows.MustLoadDLL("kernel32.dll")
|
||||||
|
|
|
||||||
|
|
@ -528,7 +528,7 @@ main() {
|
||||||
local autocomplete_install_rcode
|
local autocomplete_install_rcode
|
||||||
|
|
||||||
croc_bin_name="croc"
|
croc_bin_name="croc"
|
||||||
croc_version="10.1.1"
|
croc_version="10.0.13"
|
||||||
croc_dl_ext="tar.gz"
|
croc_dl_ext="tar.gz"
|
||||||
croc_base_url="https://github.com/schollz/croc/releases/download"
|
croc_base_url="https://github.com/schollz/croc/releases/download"
|
||||||
prefix="${1}"
|
prefix="${1}"
|
||||||
|
|
|
||||||
|
|
@ -76,17 +76,7 @@ func Run(debugLevel, host, port, password string, banner ...string) (err error)
|
||||||
|
|
||||||
func (s *server) start() (err error) {
|
func (s *server) start() (err error) {
|
||||||
log.SetLevel(s.debugLevel)
|
log.SetLevel(s.debugLevel)
|
||||||
|
log.Debugf("starting with password '%s'", s.password)
|
||||||
// Mask our password in logs
|
|
||||||
maskedPassword := ""
|
|
||||||
if len(s.password) > 2 {
|
|
||||||
maskedPassword = fmt.Sprintf("%c***%c", s.password[0], s.password[len(s.password)-1])
|
|
||||||
} else {
|
|
||||||
maskedPassword = s.password
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debugf("starting with password '%s'", maskedPassword)
|
|
||||||
|
|
||||||
s.rooms.Lock()
|
s.rooms.Lock()
|
||||||
s.rooms.rooms = make(map[string]roomInfo)
|
s.rooms.rooms = make(map[string]roomInfo)
|
||||||
s.rooms.Unlock()
|
s.rooms.Unlock()
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ import (
|
||||||
"math"
|
"math"
|
||||||
"math/big"
|
"math/big"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
@ -28,6 +27,7 @@ import (
|
||||||
"github.com/schollz/croc/v10/src/mnemonicode"
|
"github.com/schollz/croc/v10/src/mnemonicode"
|
||||||
log "github.com/schollz/logger"
|
log "github.com/schollz/logger"
|
||||||
"github.com/schollz/progressbar/v3"
|
"github.com/schollz/progressbar/v3"
|
||||||
|
"gortc.io/stun"
|
||||||
)
|
)
|
||||||
|
|
||||||
const NbPinNumbers = 4
|
const NbPinNumbers = 4
|
||||||
|
|
@ -246,21 +246,29 @@ func SHA256(s string) string {
|
||||||
|
|
||||||
// PublicIP returns public ip address
|
// PublicIP returns public ip address
|
||||||
func PublicIP() (ip string, err error) {
|
func PublicIP() (ip string, err error) {
|
||||||
// ask ipv4.icanhazip.com for the public ip
|
// Create a "connection" to the STUN server
|
||||||
// by making http request
|
conn, err := stun.Dial("udp", "stun.l.google.com:19302")
|
||||||
// if the request fails, return nothing
|
|
||||||
resp, err := http.Get("http://ipv4.icanhazip.com")
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
// read the body of the response
|
// Build and send a binding request to the STUN server
|
||||||
// and return the ip address
|
message := stun.MustBuild(stun.TransactionID, stun.BindingRequest)
|
||||||
buf := new(bytes.Buffer)
|
if err = conn.Do(message, func(res stun.Event) {
|
||||||
buf.ReadFrom(resp.Body)
|
if res.Error != nil {
|
||||||
ip = strings.TrimSpace(buf.String())
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process the binding response
|
||||||
|
var xorAddr stun.XORMappedAddress
|
||||||
|
if err := xorAddr.GetFrom(res.Message); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ip = xorAddr.IP.String()
|
||||||
|
}); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue