diff options
Diffstat (limited to 'pkg/api/api0/server.go')
-rw-r--r-- | pkg/api/api0/server.go | 51 |
1 files changed, 44 insertions, 7 deletions
diff --git a/pkg/api/api0/server.go b/pkg/api/api0/server.go index f26f7d7..c7f4f46 100644 --- a/pkg/api/api0/server.go +++ b/pkg/api/api0/server.go @@ -5,6 +5,7 @@ import ( "encoding/json" "errors" "fmt" + "math/rand" "net/http" "net/netip" "strconv" @@ -12,7 +13,6 @@ import ( "time" "github.com/pg9182/ip2x" - "github.com/r2northstar/atlas/pkg/a2s" "github.com/r2northstar/atlas/pkg/api/api0/api0gameserver" "github.com/rs/zerolog/hlog" ) @@ -391,18 +391,18 @@ func (h *Handler) handleServerUpsert(w http.ResponseWriter, r *http.Request) { } } - if err := a2s.Probe(s.Addr, time.Until(nsrv.VerificationDeadline)); err != nil { - var code ErrorCode + if err := h.probeUDP(ctx, s.Addr); err != nil { + var obj ErrorObj switch { - case errors.Is(err, a2s.ErrTimeout): + case errors.Is(err, context.DeadlineExceeded): h.m().server_upsert_requests_total.reject_verify_udptimeout(action).Inc() - code = ErrorCode_NO_GAMESERVER_RESPONSE + obj = ErrorCode_NO_GAMESERVER_RESPONSE.MessageObjf("failed to connect to game port") default: h.m().server_upsert_requests_total.reject_verify_udperr(action).Inc() - code = ErrorCode_BAD_GAMESERVER_RESPONSE + obj = ErrorCode_INTERNAL_SERVER_ERROR.MessageObjf("failed to connect to game port: %v", err) } h.m().server_upsert_verify_time_seconds.failure.UpdateDuration(verifyStart) - respFail(w, r, http.StatusBadGateway, code.MessageObjf("failed to connect to game port: %v", err)) + respFail(w, r, http.StatusBadGateway, obj) return } @@ -425,6 +425,43 @@ func (h *Handler) handleServerUpsert(w http.ResponseWriter, r *http.Request) { }) } +func (h *Handler) probeUDP(ctx context.Context, addr netip.AddrPort) error { + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + uid := rand.Uint64() + + x := make(chan error, 1) + go func() { + t := time.NewTicker(time.Second * 3) // note: we don't want to exceed the connectionless rate limit + defer t.Stop() + + for { + if err := h.NSPkt.SendConnect(addr, uid); err != nil { + select { + case x <- err: + default: + } + } + select { + case <-ctx.Done(): + return + case <-t.C: + } + } + }() + + err := h.NSPkt.WaitConnectReply(ctx, addr, uid) + if err != nil { + select { + case err = <-x: + // error could be due to an issue sending the packet + default: + } + } + return err +} + func (h *Handler) handleServerRemove(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodOptions && r.Method != http.MethodDelete { h.m().server_remove_requests_total.http_method_not_allowed.Inc() |