2021-11-12 09:37:28 +00:00
|
|
|
package pogs
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
"net"
|
2021-12-02 11:02:27 +00:00
|
|
|
"time"
|
2021-11-12 09:37:28 +00:00
|
|
|
|
|
|
|
"github.com/cloudflare/cloudflared/tunnelrpc"
|
|
|
|
"github.com/google/uuid"
|
|
|
|
capnp "zombiezen.com/go/capnproto2"
|
|
|
|
"zombiezen.com/go/capnproto2/rpc"
|
|
|
|
"zombiezen.com/go/capnproto2/server"
|
|
|
|
)
|
|
|
|
|
|
|
|
type SessionManager interface {
|
2022-09-09 04:42:11 +00:00
|
|
|
// RegisterUdpSession is the call provided to cloudflared to handle an incoming
|
|
|
|
// capnproto RegisterUdpSession request from the edge.
|
|
|
|
RegisterUdpSession(ctx context.Context, sessionID uuid.UUID, dstIP net.IP, dstPort uint16, closeAfterIdleHint time.Duration, traceContext string) (*RegisterUdpSessionResponse, error)
|
|
|
|
// UnregisterUdpSession is the call provided to cloudflared to handle an incoming
|
|
|
|
// capnproto UnregisterUdpSession request from the edge.
|
2021-12-14 22:52:47 +00:00
|
|
|
UnregisterUdpSession(ctx context.Context, sessionID uuid.UUID, message string) error
|
2021-11-12 09:37:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type SessionManager_PogsImpl struct {
|
|
|
|
impl SessionManager
|
|
|
|
}
|
|
|
|
|
|
|
|
func SessionManager_ServerToClient(s SessionManager) tunnelrpc.SessionManager {
|
|
|
|
return tunnelrpc.SessionManager_ServerToClient(SessionManager_PogsImpl{s})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (i SessionManager_PogsImpl) RegisterUdpSession(p tunnelrpc.SessionManager_registerUdpSession) error {
|
|
|
|
server.Ack(p.Options)
|
|
|
|
|
|
|
|
sessionIDRaw, err := p.Params.SessionId()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
sessionID, err := uuid.FromBytes(sessionIDRaw)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
dstIPRaw, err := p.Params.DstIp()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
dstIP := net.IP(dstIPRaw)
|
|
|
|
if dstIP == nil {
|
|
|
|
return fmt.Errorf("%v is not valid IP", dstIPRaw)
|
|
|
|
}
|
|
|
|
dstPort := p.Params.DstPort()
|
|
|
|
|
2021-12-02 11:02:27 +00:00
|
|
|
closeIdleAfterHint := time.Duration(p.Params.CloseAfterIdleHint())
|
|
|
|
|
2022-09-07 22:06:06 +00:00
|
|
|
traceContext, err := p.Params.TraceContext()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2022-09-09 04:42:11 +00:00
|
|
|
resp, registrationErr := i.impl.RegisterUdpSession(p.Ctx, sessionID, dstIP, dstPort, closeIdleAfterHint, traceContext)
|
2021-11-12 09:37:28 +00:00
|
|
|
if registrationErr != nil {
|
2022-09-09 04:42:11 +00:00
|
|
|
// Make sure to assign a response even if one is not returned from register
|
|
|
|
if resp == nil {
|
|
|
|
resp = &RegisterUdpSessionResponse{}
|
|
|
|
}
|
2021-11-12 09:37:28 +00:00
|
|
|
resp.Err = registrationErr
|
|
|
|
}
|
|
|
|
|
|
|
|
result, err := p.Results.NewResult()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return resp.Marshal(result)
|
|
|
|
}
|
|
|
|
|
2021-11-30 19:58:11 +00:00
|
|
|
func (i SessionManager_PogsImpl) UnregisterUdpSession(p tunnelrpc.SessionManager_unregisterUdpSession) error {
|
|
|
|
server.Ack(p.Options)
|
|
|
|
|
|
|
|
sessionIDRaw, err := p.Params.SessionId()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
sessionID, err := uuid.FromBytes(sessionIDRaw)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2021-12-14 22:52:47 +00:00
|
|
|
message, err := p.Params.Message()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return i.impl.UnregisterUdpSession(p.Ctx, sessionID, message)
|
2021-11-30 19:58:11 +00:00
|
|
|
}
|
|
|
|
|
2021-11-12 09:37:28 +00:00
|
|
|
type RegisterUdpSessionResponse struct {
|
2022-09-07 22:06:06 +00:00
|
|
|
Err error
|
|
|
|
Spans []byte // Spans in protobuf format
|
2021-11-12 09:37:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (p *RegisterUdpSessionResponse) Marshal(s tunnelrpc.RegisterUdpSessionResponse) error {
|
|
|
|
if p.Err != nil {
|
|
|
|
return s.SetErr(p.Err.Error())
|
|
|
|
}
|
2022-09-07 22:06:06 +00:00
|
|
|
if err := s.SetSpans(p.Spans); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2021-11-12 09:37:28 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *RegisterUdpSessionResponse) Unmarshal(s tunnelrpc.RegisterUdpSessionResponse) error {
|
|
|
|
respErr, err := s.Err()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if respErr != "" {
|
|
|
|
p.Err = fmt.Errorf(respErr)
|
|
|
|
}
|
2022-09-07 22:06:06 +00:00
|
|
|
p.Spans, err = s.Spans()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2021-11-12 09:37:28 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
type SessionManager_PogsClient struct {
|
|
|
|
Client capnp.Client
|
|
|
|
Conn *rpc.Conn
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c SessionManager_PogsClient) Close() error {
|
|
|
|
c.Client.Close()
|
|
|
|
return c.Conn.Close()
|
|
|
|
}
|
|
|
|
|
2022-09-07 22:06:06 +00:00
|
|
|
func (c SessionManager_PogsClient) RegisterUdpSession(ctx context.Context, sessionID uuid.UUID, dstIP net.IP, dstPort uint16, closeAfterIdleHint time.Duration, traceContext string) (*RegisterUdpSessionResponse, error) {
|
2021-11-12 09:37:28 +00:00
|
|
|
client := tunnelrpc.SessionManager{Client: c.Client}
|
|
|
|
promise := client.RegisterUdpSession(ctx, func(p tunnelrpc.SessionManager_registerUdpSession_Params) error {
|
|
|
|
if err := p.SetSessionId(sessionID[:]); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := p.SetDstIp(dstIP); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
p.SetDstPort(dstPort)
|
2021-12-02 11:02:27 +00:00
|
|
|
p.SetCloseAfterIdleHint(int64(closeAfterIdleHint))
|
2022-09-07 22:06:06 +00:00
|
|
|
p.SetTraceContext(traceContext)
|
2021-11-12 09:37:28 +00:00
|
|
|
return nil
|
|
|
|
})
|
|
|
|
result, err := promise.Result().Struct()
|
|
|
|
if err != nil {
|
|
|
|
return nil, wrapRPCError(err)
|
|
|
|
}
|
|
|
|
response := new(RegisterUdpSessionResponse)
|
|
|
|
|
|
|
|
err = response.Unmarshal(result)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return response, nil
|
|
|
|
}
|
2021-11-30 19:58:11 +00:00
|
|
|
|
2021-12-14 22:52:47 +00:00
|
|
|
func (c SessionManager_PogsClient) UnregisterUdpSession(ctx context.Context, sessionID uuid.UUID, message string) error {
|
2021-11-30 19:58:11 +00:00
|
|
|
client := tunnelrpc.SessionManager{Client: c.Client}
|
|
|
|
promise := client.UnregisterUdpSession(ctx, func(p tunnelrpc.SessionManager_unregisterUdpSession_Params) error {
|
|
|
|
if err := p.SetSessionId(sessionID[:]); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2021-12-14 22:52:47 +00:00
|
|
|
if err := p.SetMessage(message); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2021-11-30 19:58:11 +00:00
|
|
|
return nil
|
|
|
|
})
|
|
|
|
_, err := promise.Struct()
|
|
|
|
return err
|
|
|
|
}
|