mirror of
https://github.com/hackdiaz-dev/free-turn-proxy.git
synced 2026-10-12 09:41:53 +02:00
ci: запинить версии gomobile, goimports и docker-действия
This commit is contained in:
@@ -16,7 +16,7 @@ env:
|
||||
GOLANGCI_VERSION: v2.12.2
|
||||
GOVULN_VERSION: v1.6.0
|
||||
GORELEASER_VERSION: v2.17.1
|
||||
GOMOBILE_VERSION: latest
|
||||
GOMOBILE_VERSION: v0.0.0-20260821190718-4776eadac327
|
||||
TASK_VERSION: 3.52.0
|
||||
|
||||
jobs:
|
||||
|
||||
@@ -12,7 +12,7 @@ permissions:
|
||||
env:
|
||||
GO_VERSION: "1.26.7"
|
||||
GORELEASER_VERSION: v2.17.1
|
||||
GOMOBILE_VERSION: latest
|
||||
GOMOBILE_VERSION: v0.0.0-20260821190718-4776eadac327
|
||||
TASK_VERSION: 3.52.0
|
||||
|
||||
jobs:
|
||||
@@ -120,7 +120,7 @@ jobs:
|
||||
echo "EOF"
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
|
||||
- uses: docker/build-push-action@v6
|
||||
- uses: docker/build-push-action@v6.19.2
|
||||
with:
|
||||
context: .
|
||||
file: docker/awg/Dockerfile
|
||||
|
||||
+2
-1
@@ -7,6 +7,7 @@ vars:
|
||||
LDFLAGS: -s -w -checklinkname=0 -X main.version={{.VERSION}}
|
||||
GOLANGCI_VERSION: v2.12.2
|
||||
GOVULN_VERSION: v1.6.0
|
||||
GOIMPORTS_VERSION: v0.49.0
|
||||
GORELEASER_VERSION: v2.17.1
|
||||
TASK_VERSION: v3.52.0
|
||||
|
||||
@@ -125,7 +126,7 @@ tasks:
|
||||
tools:install:
|
||||
desc: Install dev tools (golangci-lint, govulncheck, goreleaser, goimports)
|
||||
cmds:
|
||||
- go install golang.org/x/tools/cmd/goimports@latest
|
||||
- go install golang.org/x/tools/cmd/goimports@{{.GOIMPORTS_VERSION}}
|
||||
- go install golang.org/x/vuln/cmd/govulncheck@{{.GOVULN_VERSION}}
|
||||
- go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@{{.GOLANGCI_VERSION}}
|
||||
- go install github.com/goreleaser/goreleaser/v2@{{.GORELEASER_VERSION}}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
// Package shutdown связывает сигналы ОС с отменой контекста процесса.
|
||||
package shutdown
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/samosvalishe/free-turn-proxy/internal/logx"
|
||||
)
|
||||
|
||||
// Grace - время на доработку после отмены контекста.
|
||||
const Grace = 5 * time.Second
|
||||
|
||||
// Watch отменяет ctx по SIGINT/SIGTERM. Возвращённый stop снимает обработчик при
|
||||
// штатном выходе - без него процесс уходил бы в форс-выход с кодом 1 на каждой остановке.
|
||||
func Watch(parent context.Context, log logx.Logger) (context.Context, func()) {
|
||||
log = logx.OrNop(log)
|
||||
ctx, cancel := context.WithCancel(parent)
|
||||
|
||||
sig := make(chan os.Signal, 1)
|
||||
signal.Notify(sig, syscall.SIGTERM, syscall.SIGINT)
|
||||
done := make(chan struct{})
|
||||
|
||||
go func() {
|
||||
select {
|
||||
case <-sig:
|
||||
case <-done:
|
||||
return
|
||||
}
|
||||
log.Infof("Terminating...")
|
||||
cancel()
|
||||
select {
|
||||
case <-sig:
|
||||
log.Warnf("Forced exit on second signal")
|
||||
case <-done:
|
||||
return
|
||||
case <-time.After(Grace):
|
||||
log.Warnf("Forced exit after %s shutdown timeout", Grace)
|
||||
}
|
||||
// Форс-выход сжигает defer-ы (в том числе снятие host-маршрутов) - только как крайняя мера.
|
||||
os.Exit(1)
|
||||
}()
|
||||
|
||||
return ctx, func() {
|
||||
signal.Stop(sig)
|
||||
close(done)
|
||||
cancel()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package wire
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
dtlsnet "github.com/pion/dtls/v3/pkg/net"
|
||||
pionudp "github.com/pion/transport/v4/udp"
|
||||
)
|
||||
|
||||
// NewServerCodec создаёт кодек для очередного принятого соединения: состояние RTP-сессии
|
||||
// у каждого клиента своё, общий у профиля только ключ.
|
||||
type NewServerCodec func() (Codec, error)
|
||||
|
||||
// ListenCodec - единственная серверная обвязка на все профили: они отличались только
|
||||
// именем пакета в текстах ошибок.
|
||||
func ListenCodec(addr *net.UDPAddr, newCodec NewServerCodec) (dtlsnet.PacketListener, error) {
|
||||
inner, err := pionudp.Listen("udp", addr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("wire: udp listen: %w", err)
|
||||
}
|
||||
return &packetListener{inner: dtlsnet.PacketListenerFromListener(inner), newCodec: newCodec}, nil
|
||||
}
|
||||
|
||||
type packetListener struct {
|
||||
inner dtlsnet.PacketListener
|
||||
newCodec NewServerCodec
|
||||
}
|
||||
|
||||
func (l *packetListener) Accept() (net.PacketConn, net.Addr, error) {
|
||||
pc, addr, err := l.inner.Accept()
|
||||
if err != nil {
|
||||
return pc, addr, err
|
||||
}
|
||||
codec, err := l.newCodec()
|
||||
if err != nil {
|
||||
return nil, addr, err
|
||||
}
|
||||
return &RelayPacketConn{Relay: pc, Codec: codec}, addr, nil
|
||||
}
|
||||
|
||||
func (l *packetListener) Close() error { return l.inner.Close() }
|
||||
func (l *packetListener) Addr() net.Addr { return l.inner.Addr() }
|
||||
@@ -0,0 +1,79 @@
|
||||
package wire
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"net"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Серверная обвязка общая для всех профилей - проверяем каждый через реальный UDP.
|
||||
func TestListenCodecRoundTrip(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
for _, profile := range []string{ProfileRTPOpus, ProfileRTPOpus2, ProfileRTPOpus3} {
|
||||
t.Run(profile, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
key := make([]byte, 32)
|
||||
if _, err := rand.Read(key); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
ln, err := Listen(profile, &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1)}, key)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer func() { _ = ln.Close() }()
|
||||
|
||||
raw, err := net.ListenUDP("udp", &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1)})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer func() { _ = raw.Close() }()
|
||||
|
||||
codec, err := NewClientCodec(profile, key)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
client := &RelayPacketConn{Relay: raw, Peer: ln.Addr(), Codec: codec}
|
||||
|
||||
want := []byte("obfuscated payload")
|
||||
if _, err = client.WriteTo(want, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
srv, _, err := ln.Accept()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer func() { _ = srv.Close() }()
|
||||
|
||||
buf := make([]byte, 1500)
|
||||
if err = srv.SetReadDeadline(time.Now().Add(5 * time.Second)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
n, from, err := srv.ReadFrom(buf)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if string(buf[:n]) != string(want) {
|
||||
t.Fatalf("server got %q, want %q", buf[:n], want)
|
||||
}
|
||||
|
||||
// Peer у серверной стороны пустой: ответ обязан уйти отправителю.
|
||||
if _, err = srv.WriteTo(buf[:n], from); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err = client.SetReadDeadline(time.Now().Add(5 * time.Second)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
n, _, err = client.ReadFrom(buf)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if string(buf[:n]) != string(want) {
|
||||
t.Fatalf("client got %q, want %q", buf[:n], want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user