diff --git a/Dockerfile.turn b/Dockerfile.turn new file mode 100644 index 00000000..ccdd66f1 --- /dev/null +++ b/Dockerfile.turn @@ -0,0 +1,21 @@ +#first stage - builder +FROM gravitl/go-builder as builder + +ARG version + +WORKDIR /app + +COPY . . + +WORKDIR /app/turnserver +ENV GO111MODULE=auto + +RUN GOOS=linux CGO_ENABLED=1 go build -ldflags="-s -X 'main.version=${version}'" -o turnserver main.go +FROM alpine:3.15.2 + +# set the working directory +WORKDIR /root/ + +COPY --from=builder /app/turnserver/turnserver . + +ENTRYPOINT ["./turnserver"] \ No newline at end of file diff --git a/go.mod b/go.mod index 14b61e58..da950b17 100644 --- a/go.mod +++ b/go.mod @@ -41,24 +41,39 @@ require ( ) require ( + github.com/gin-gonic/gin v1.9.0 github.com/guumaster/tablewriter v0.0.10 github.com/matryer/is v1.4.1 github.com/olekukonko/tablewriter v0.0.5 github.com/pion/turn/v2 v2.1.0 github.com/spf13/cobra v1.6.1 + github.com/ulule/limiter/v3 v3.11.1 ) require ( cloud.google.com/go/compute/metadata v0.2.1 // indirect + github.com/bytedance/sonic v1.8.0 // indirect + github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect + github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-jose/go-jose/v3 v3.0.0 // indirect + github.com/goccy/go-json v0.10.0 // indirect github.com/inconshreveable/mousetrap v1.0.1 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/cpuid/v2 v2.0.9 // indirect github.com/kr/pretty v0.3.1 // indirect + github.com/mattn/go-isatty v0.0.17 // indirect + github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/pelletier/go-toml/v2 v2.0.6 // indirect github.com/pion/logging v0.2.2 // indirect github.com/pion/randutil v0.1.0 // indirect github.com/pion/stun v0.4.0 // indirect github.com/pion/transport/v2 v2.0.0 // indirect github.com/rivo/uniseg v0.2.0 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/ugorji/go/codec v1.2.9 // indirect + golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect ) require ( diff --git a/go.sum b/go.sum index d36d08a9..ef5badcb 100644 --- a/go.sum +++ b/go.sum @@ -7,8 +7,14 @@ filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek= filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= +github.com/bytedance/sonic v1.8.0 h1:ea0Xadu+sHlu7x5O3gKhRpQ1IKiMrSiHttPF0ybECuA= +github.com/bytedance/sonic v1.8.0/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= github.com/c-robinson/iplib v1.0.6 h1:FfZV9BWNrah3BgLCFl5/nDXe4RbOi/C9n+DeXFOv5CQ= github.com/c-robinson/iplib v1.0.6/go.mod h1:i3LuuFL1hRT5gFpBRnEydzw8R6yhGkF4szNDIbF8pgo= +github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= +github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= +github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-oidc/v3 v3.5.0 h1:VxKtbccHZxs8juq7RdJntSqtXFtde9YpNpGn0yqgEHw= @@ -27,6 +33,10 @@ github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSw github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.9.0 h1:OjyFBKICoexlu99ctXNR2gg+c5pKrKMuyjgARg9qeY8= +github.com/gin-gonic/gin v1.9.0/go.mod h1:W1Me9+hsUSyj3CePGrd1/QrKJMSJ1Tu/0hFEH89961k= github.com/go-jose/go-jose/v3 v3.0.0 h1:s6rrhirfEP/CGIoc6p+PZAeogN2SxKav6Wp7+dyMWVo= github.com/go-jose/go-jose/v3 v3.0.0/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= @@ -36,6 +46,8 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.11.2 h1:q3SHpufmypg+erIExEKUmsgmhDTyhcJ38oeKGACXohU= github.com/go-playground/validator/v10 v10.11.2/go.mod h1:NieE624vt4SCTJtD87arVLvdmjPAeV8BQlHtMnw9D7s= +github.com/goccy/go-json v0.10.0 h1:mXKd9Qw4NuzShiRlOXKews24ufknHO7gx30lsDyokKA= +github.com/goccy/go-json v0.10.0/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -49,6 +61,7 @@ github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8 github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= @@ -68,6 +81,10 @@ github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7P github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/josharian/native v1.0.0 h1:Ts/E8zCSEsG17dUqv7joXJFybuMLjQfWE04tsBODTxk= github.com/josharian/native v1.0.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -82,6 +99,8 @@ github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/matryer/is v1.4.1 h1:55ehd8zaGABKLXQUe2awZ99BD/PTc2ls+KV/dXphgEQ= github.com/matryer/is v1.4.1/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= +github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= +github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= @@ -98,9 +117,15 @@ github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721 h1:RlZweED6sbSArvlE9 github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721/go.mod h1:Ickgr2WtCLZ2MDGd4Gr0geeCH5HybhRJbonOgQpvSxc= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU= +github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA= @@ -145,6 +170,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -152,14 +178,22 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/txn2/txeh v1.3.0 h1:vnbv63htVMZCaQgLqVBxKvj2+HHHFUzNW7I183zjg3E= github.com/txn2/txeh v1.3.0/go.mod h1:O7M6gUTPeMF+vsa4c4Ipx3JDkOYrruB1Wry8QRsMcw8= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ugorji/go/codec v1.2.9 h1:rmenucSohSTiyL09Y+l2OCk+FrMxGMzho2+tjr5ticU= +github.com/ugorji/go/codec v1.2.9/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/ulule/limiter/v3 v3.11.1 h1:wm6YaA2JwIXc0S+z8TK8/neWMOTf4m20I5jL1dwLRcw= +github.com/ulule/limiter/v3 v3.11.1/go.mod h1:4nk/9RHEJthkjD+mmkqYxaPfD4pkB91PTH7k8ozB80g= github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c h1:3lbZUMbMiGUW/LMkfsEABsc5zNT9+b1CvsJx47JzJ8g= github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c/go.mod h1:UrdRz5enIKZ63MEE3IF9l2/ebyx59GyGgPi+tICQdmM= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +golang.org/x/arch v0.0.0-20210923205945-b76863e36670 h1:18EFjUmQOcUvxNYSkA6jO9VAiXCnxFY6NyDX0bHDmkU= +golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -209,6 +243,7 @@ golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220207234003-57398862261d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -256,3 +291,4 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gortc.io/stun v1.23.0 h1:CpRQFjakCZMwVKTwInKbcCzlBklj62LGzD3NPdFyGrE= gortc.io/stun v1.23.0/go.mod h1:XD5lpONVyjvV3BgOyJFNo0iv6R2oZB4L+weMqxts+zg= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/logic/hosts.go b/logic/hosts.go index b780729b..23d66204 100644 --- a/logic/hosts.go +++ b/logic/hosts.go @@ -11,7 +11,6 @@ import ( "github.com/gravitl/netmaker/logger" "github.com/gravitl/netmaker/models" "github.com/gravitl/netmaker/servercfg" - "github.com/gravitl/netmaker/turnserver" "golang.org/x/crypto/bcrypt" ) @@ -98,7 +97,7 @@ func CreateHost(h *models.Host) error { return err } h.HostPass = string(hash) - turnserver.RegisterNewHostWithTurn(h.ID.String(), h.HostPass) + //turnserver.RegisterNewHostWithTurn(h.ID.String(), h.HostPass) // if another server has already updated proxyenabled, leave it alone if !h.ProxyEnabledSet { log.Println("checking default proxy", servercfg.GetServerConfig().DefaultProxyMode) diff --git a/main.go b/main.go index 7c892c76..c899cb99 100644 --- a/main.go +++ b/main.go @@ -25,7 +25,6 @@ import ( "github.com/gravitl/netmaker/servercfg" "github.com/gravitl/netmaker/serverctl" stunserver "github.com/gravitl/netmaker/stun-server" - "github.com/gravitl/netmaker/turnserver" ) var version = "v0.18.6" @@ -148,9 +147,6 @@ func startControllers(wg *sync.WaitGroup, ctx context.Context) { // starts the stun server wg.Add(1) go stunserver.Start(wg, ctx) - // starts the turn server - wg.Add(1) - go turnserver.Start(wg, ctx) } // Should we be using a context vice a waitgroup???????????? @@ -195,7 +191,8 @@ func registerCurrHostsWithTurn() { hosts, err := logic.GetAllHosts() if err == nil { for _, hostI := range hosts { - turnserver.RegisterNewHostWithTurn(hostI.ID.String(), hostI.HostPass) + //turnserver.RegisterNewHostWithTurn(hostI.ID.String(), hostI.HostPass) + fmt.Println(hostI) } } } diff --git a/turnserver/internal/auth/auth.go b/turnserver/internal/auth/auth.go new file mode 100644 index 00000000..224b59fb --- /dev/null +++ b/turnserver/internal/auth/auth.go @@ -0,0 +1,49 @@ +package auth + +import ( + "encoding/json" + "os" + "path/filepath" + "sync" + + "github.com/gravitl/netmaker/logger" + "github.com/gravitl/netmaker/servercfg" + "github.com/pion/turn/v2" +) + +var ( + AuthMapLock = &sync.RWMutex{} + HostMap = make(map[string][]byte) + authBackUpFile = "auth.json" +) + +func RegisterNewHostWithTurn(hostID, hostPass string) { + AuthMapLock.Lock() + HostMap[hostID] = turn.GenerateAuthKey(hostID, servercfg.GetTurnHost(), hostPass) + dumpCredsToFile() + AuthMapLock.Unlock() +} + +func UnRegisterNewHostWithTurn(hostID string) { + AuthMapLock.Lock() + delete(HostMap, hostID) + dumpCredsToFile() + AuthMapLock.Unlock() +} + +func dumpCredsToFile() { + d, err := json.MarshalIndent(HostMap, "", " ") + if err != nil { + logger.Log(0, "failed to dump creds to file: ", err.Error()) + return + } + userHomeDir, err := os.UserHomeDir() + if err != nil { + logger.Log(0, "failed to get user's home directory") + return + } + err = os.WriteFile(filepath.Join(userHomeDir, authBackUpFile), d, os.ModePerm) + if err != nil { + logger.Log(0, "failed to backup auth data: ", userHomeDir, err.Error()) + } +} diff --git a/turnserver/internal/errors/api_errors.go b/turnserver/internal/errors/api_errors.go new file mode 100644 index 00000000..6c3e9a33 --- /dev/null +++ b/turnserver/internal/errors/api_errors.go @@ -0,0 +1,48 @@ +package errors + +import ( + "net/http" + + "github.com/gravitl/netmaker/turnserver/internal/models" +) + +type ApiRespErr string + +const ( + Internal ApiRespErr = "internal" + BadRequest ApiRespErr = "badrequest" + NotFound ApiRespErr = "notfound" + UnAuthorized ApiRespErr = "unauthorized" + Forbidden ApiRespErr = "forbidden" + Unavailable ApiRespErr = "unavailable" +) + +// FormatError - formats into api error resp +func FormatError(err error, errType ApiRespErr) models.ErrorResponse { + + var status = http.StatusInternalServerError + switch errType { + case Internal: + status = http.StatusInternalServerError + case BadRequest: + status = http.StatusBadRequest + case NotFound: + status = http.StatusNotFound + case UnAuthorized: + status = http.StatusUnauthorized + case Forbidden: + status = http.StatusForbidden + case Unavailable: + status = http.StatusServiceUnavailable + default: + status = http.StatusInternalServerError + } + + var response = models.ErrorResponse{ + Code: status, + } + if err != nil { + response.Message = err.Error() + } + return response +} diff --git a/turnserver/internal/host/host.go b/turnserver/internal/host/host.go new file mode 100644 index 00000000..df31b1cc --- /dev/null +++ b/turnserver/internal/host/host.go @@ -0,0 +1,37 @@ +package host + +import ( + "errors" + "fmt" + + "github.com/gin-gonic/gin" + + "github.com/gravitl/netmaker/logger" + "github.com/gravitl/netmaker/turnserver/internal/auth" + errpkg "github.com/gravitl/netmaker/turnserver/internal/errors" + "github.com/gravitl/netmaker/turnserver/internal/models" + "github.com/gravitl/netmaker/turnserver/internal/utils" +) + +func Register(c *gin.Context) { + req := models.HostRegister{} + if err := c.ShouldBindJSON(&req); err != nil { + utils.ReturnErrorResponse(c, errpkg.FormatError(err, errpkg.Internal)) + return + } + auth.RegisterNewHostWithTurn(req.HostID, req.HostPassHash) + utils.ReturnSuccessResponse(c, + fmt.Sprintf("registred host (%s) successfully", req.HostID), nil) +} + +func Remove(c *gin.Context) { + hostID, _ := c.GetQuery("host_id") + if hostID == "" { + logger.Log(0, "host id is required") + utils.ReturnErrorResponse(c, + errpkg.FormatError(errors.New("host id is required"), errpkg.BadRequest)) + return + } + utils.ReturnSuccessResponse(c, + fmt.Sprintf("unregistred host (%s) successfully", hostID), nil) +} diff --git a/turnserver/internal/models/models.go b/turnserver/internal/models/models.go new file mode 100644 index 00000000..0b9347d2 --- /dev/null +++ b/turnserver/internal/models/models.go @@ -0,0 +1,6 @@ +package models + +type HostRegister struct { + HostID string `json:"host_id"` + HostPassHash string `json:"host_pass_hash"` +} diff --git a/turnserver/internal/models/response.go b/turnserver/internal/models/response.go new file mode 100644 index 00000000..9d605ed5 --- /dev/null +++ b/turnserver/internal/models/response.go @@ -0,0 +1,14 @@ +package models + +// ErrorResponse is struct for error +type ErrorResponse struct { + Code int `json:"code"` + Message string `json:"message"` +} + +// SuccessResponse is struct for sending error message with code. +type SuccessResponse struct { + Code int `json:"code"` + Message string `json:"message"` + Response interface{} `json:"response"` +} diff --git a/turnserver/internal/utils/response.go b/turnserver/internal/utils/response.go new file mode 100644 index 00000000..71457e82 --- /dev/null +++ b/turnserver/internal/utils/response.go @@ -0,0 +1,36 @@ +package utils + +import ( + "net/http" + + "github.com/gin-gonic/gin" + "github.com/gravitl/netmaker/turnserver/internal/models" +) + +// ReturnSuccessResponse - success api response +// ReturnSuccessResponse - success api response +func ReturnSuccessResponse(c *gin.Context, message string, responseBody interface{}) { + var httpResponse models.SuccessResponse + httpResponse.Code = http.StatusOK + httpResponse.Message = message + httpResponse.Response = responseBody + if httpResponse.Response == nil { + httpResponse.Response = struct{}{} + } + c.Writer.Header().Set("Content-Type", "application/json") + c.JSON(http.StatusOK, httpResponse) +} + +// ReturnErrorResponse - error api response +func ReturnErrorResponse(c *gin.Context, errorMessage models.ErrorResponse) { + httpResponse := &models.ErrorResponse{Code: errorMessage.Code, Message: errorMessage.Message} + c.Writer.Header().Set("Content-Type", "application/json") + c.JSON(errorMessage.Code, httpResponse) +} + +// AbortWithError - abort api request with error +func AbortWithError(c *gin.Context, errorMessage models.ErrorResponse) { + httpResponse := &models.ErrorResponse{Code: errorMessage.Code, Message: errorMessage.Message} + c.Writer.Header().Set("Content-Type", "application/json") + c.AbortWithStatusJSON(errorMessage.Code, httpResponse) +} diff --git a/turnserver/internal/utils/utils.go b/turnserver/internal/utils/utils.go new file mode 100644 index 00000000..d69b4042 --- /dev/null +++ b/turnserver/internal/utils/utils.go @@ -0,0 +1,46 @@ +package utils + +import ( + "errors" + "io" + "net/http" + "time" +) + +// GetPublicIP - gets public ip +func GetPublicIP() (string, error) { + + iplist := []string{"https://ip.client.gravitl.com", "https://ifconfig.me", "https://api.ipify.org", "https://ipinfo.io/ip"} + + //for network, ipService := range global_settings.PublicIPServices { + //logger.Log(3, "User provided public IP service defined for network", network, "is", ipService) + + // prepend the user-specified service so it's checked first + // iplist = append([]string{ipService}, iplist...) + //} + + endpoint := "" + var err error + for _, ipserver := range iplist { + client := &http.Client{ + Timeout: time.Second * 10, + } + resp, err := client.Get(ipserver) + if err != nil { + continue + } + defer resp.Body.Close() + if resp.StatusCode == http.StatusOK { + bodyBytes, err := io.ReadAll(resp.Body) + if err != nil { + continue + } + endpoint = string(bodyBytes) + break + } + } + if err == nil && endpoint == "" { + err = errors.New("public address not found") + } + return endpoint, err +} diff --git a/turnserver/main.go b/turnserver/main.go new file mode 100644 index 00000000..a2eed106 --- /dev/null +++ b/turnserver/main.go @@ -0,0 +1,34 @@ +package main + +import ( + "context" + "os" + "os/signal" + "sync" + "syscall" + + "github.com/gravitl/netmaker/logger" + "github.com/gravitl/netmaker/turnserver/src/controller" + "github.com/gravitl/netmaker/turnserver/src/turn" +) + +func main() { + ctx, cancel := context.WithCancel(context.Background()) + wg := &sync.WaitGroup{} + // Wait for interrupt signal to gracefully shutdown the server with + // a timeout of 5 seconds. + quit := make(chan os.Signal, 2) + // kill (no param) default send syscanll.SIGTERM + // kill -2 is syscall.SIGINT + // kill -9 is syscall. SIGKILL but cant be caught, so don't need add it + wg.Add(1) + controller.HandleRESTRequests(ctx, wg) + wg.Add(1) + turn.Start(ctx, wg) + signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) + <-quit + logger.Log(0, "Recieved Shutdown Signal...") + cancel() + wg.Wait() + logger.Log(0, "Stopping Turn Server...") +} diff --git a/turnserver/src/routes/routes.go b/turnserver/src/routes/routes.go index 772c8631..673b56b2 100644 --- a/turnserver/src/routes/routes.go +++ b/turnserver/src/routes/routes.go @@ -1,7 +1,17 @@ package routes -import "github.com/gin-gonic/gin" +import ( + "github.com/gin-gonic/gin" + "github.com/gravitl/netmaker/turnserver/internal/host" +) func Init(r *gin.Engine) *gin.Engine { + api := r.Group("/api") + v1 := api.Group("/v1") + registerRoutes(v1) return r } + +func registerRoutes(r *gin.RouterGroup) { + r.POST("/host/register", host.Register) +} diff --git a/turnserver/turnserver.go b/turnserver/src/turn/server.go similarity index 73% rename from turnserver/turnserver.go rename to turnserver/src/turn/server.go index dea37b70..223588b0 100644 --- a/turnserver/turnserver.go +++ b/turnserver/src/turn/server.go @@ -1,4 +1,4 @@ -package turnserver +package turn import ( "context" @@ -10,18 +10,12 @@ import ( "github.com/gravitl/netmaker/logger" "github.com/gravitl/netmaker/servercfg" + "github.com/gravitl/netmaker/turnserver/internal/auth" + "github.com/gravitl/netmaker/turnserver/internal/utils" "github.com/pion/turn/v2" ) -var ( - UsersMap = make(map[string][]byte) -) - -func RegisterNewHostWithTurn(hostID, hostPass string) { - UsersMap[hostID] = turn.GenerateAuthKey(hostID, servercfg.GetTurnHost(), hostPass) -} - -func Start(wg *sync.WaitGroup, ctx context.Context) { +func Start(ctx context.Context, wg *sync.WaitGroup) { defer wg.Done() // Create a UDP listener to pass into pion/turn // pion/turn itself doesn't allocate any UDP sockets, but lets the user pass them in @@ -30,14 +24,17 @@ func Start(wg *sync.WaitGroup, ctx context.Context) { if err != nil { log.Panicf("Failed to create TURN server listener: %s", err) } - + publicIP, err := utils.GetPublicIP() + if err != nil { + logger.FatalLog("failed to get public ip: ", err.Error()) + } s, err := turn.NewServer(turn.ServerConfig{ Realm: servercfg.GetTurnHost(), // Set AuthHandler callback // This is called every time a user tries to authenticate with the TURN server // Return the key for that user, or false when no user is found AuthHandler: func(username string, realm string, srcAddr net.Addr) ([]byte, bool) { - if key, ok := UsersMap[username]; ok { + if key, ok := auth.HostMap[username]; ok { return key, true } return nil, false @@ -47,8 +44,8 @@ func Start(wg *sync.WaitGroup, ctx context.Context) { { PacketConn: udpListener, RelayAddressGenerator: &turn.RelayAddressGeneratorStatic{ - RelayAddress: net.ParseIP("64.227.178.89"), // Claim that we are listening on IP passed by user (This should be your Public IP) - Address: "0.0.0.0", // But actually be listening on every interface + RelayAddress: net.ParseIP(publicIP), // Claim that we are listening on IP passed by user (This should be your Public IP) + Address: "0.0.0.0", // But actually be listening on every interface }, }, }, @@ -60,7 +57,6 @@ func Start(wg *sync.WaitGroup, ctx context.Context) { for { time.Sleep(time.Second * 10) log.Print(s.AllocationCount()) - } }()