diagox

package module
v0.1.1-0...-75bc462 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 21, 2026 License: MPL-2.0 Imports: 48 Imported by: 0

README

Diagox

Diagox

SIP and media ingress for modern voice systems
Route, bridge, and connect real-time communications across SIP, RTP, and WebRTC.

[!IMPORTANT] ☁️ Cloud-friendly by design. Diagox fits local, containerized, and distributed deployments. Managed deployments can remotely provision endpoints and routing for fast operational changes, enabling automation and AI-assisted configuration workflows.

Diagox is programmable SIP and media ingress for modern voice systems, built around a purpose-built signaling and media B2BUA with an integrated media proxy. It connects PBXs, SIP providers, WebRTC clients, internal voice services, and other reachable telephony endpoints. Diagox provides selected Session Border Controller (SBC) capabilities—including topology hiding, authentication, rate limiting, and call observability—without positioning itself as a full carrier-grade SBC. It runs as a single Go binary and is built on top of sipgo and diago.

What Diagox provides

  • SIP ingress and egress over UDP, TCP, and WebSocket transports
  • RTP and WebRTC media ingress, egress, and proxying
  • B2BUA call routing and dialog bridging between endpoints
  • Browser-friendly SIP/WebSocket connectivity
  • Registrar and in-memory contact registry support
  • Programmable routes with prefixes, fallback destinations, and hangup rules
  • Call recording, media statistics, and VoIP monitoring
  • YAML-based configuration suitable for local deployments and containers

Get started

The fastest way to explore Diagox is to start with the minimal configuration:

go install ./cmd/diagox

CONF_FILE=example-configs/diagox-minimal.yaml diagox

The configuration expects an endpoint named bob at sip:internal.network:5080. Update that destination for your environment.

For container-based deployments, build the included image and provide the configuration through the image or a mounted file:

docker build -t diagox .
docker run --rm \
  -p 5060:5060/udp \
  -v "$PWD/example-configs/diagox-minimal.yaml:/app/diagox.yaml:ro" \
  diagox
Diago load test

The repository includes a Diago-based load generator. It runs an in-process UAS on port 5080, originates concurrent calls to the configured Diagox SIP target, and sends/receives PCMU RTP for every answered call. Configure Diagox to route its outbound leg to sip:127.0.0.1:5080, then run:

go run ./cmd/diagox-loadtest \
  -target sip:1000@127.0.0.1:5060 \
  -uas-listen 127.0.0.1:5080 \
  -calls 100 \
  -rate 10 \
  -concurrency 50 \
  -duration 60s

Use -calls 0 to run until interrupted, -media=false for SIP-only load, and -metrics-addr :9091 to expose load-generator metrics at http://localhost:9091/metrics. Diagox exposes its application metrics at http://localhost:6060/metrics.

See the installation guide for runtime configuration, networking, and deployment details.

Example configurations

All example configurations are included in the repository:

Example Use it for
diagox-minimal.yaml A small SIP routing and recording setup.
diagox-webrtc.yaml SIP plus WebRTC/WebSocket endpoints.
diagox_full.yaml A broader example with route contexts, carrier endpoints, authentication, and header handling.
diagox_docker.yaml Docker-oriented transports, registry routing, and carrier fallbacks.

The examples contain placeholder addresses and credentials. Replace them before using any configuration outside a local test environment.

Core concepts

Diagox configuration is organized around three pieces:

  • Transports define where Diagox listens for SIP traffic, including UDP, TCP, and WebSocket listeners.
  • Endpoints identify incoming callers or define destinations such as PBXs, carriers, registered users, and WebRTC clients.
  • Routes decide where calls go based on the endpoint, dialed number, prefixes, registration state, and other matching rules.

This keeps the call-routing policy separate from the service process and makes it possible to adapt the same gateway to different networks and providers.

Documentation

Open source and scalable (enterprise)

The open-source Diagox distribution provides a focused, single-instance voice gateway that can be run as a binary or container.

Scalable capabilities are available separately for deployments that need:

  • Multiple coordinated Diagox instances
  • Kubernetes deployment charts
  • External registry caching
  • Database-backed call detail records
  • Centralized management and remote provisioning of instances and SIP/media ingress configuration

For more information about scalable deployments, contact mail.

Development

Build the server with:

go install ./cmd/diagox

Run the Go test suite with:

go test ./...

Diagox is licensed under the Mozilla Public License 2.0.

Documentation

Index

Constants

View Source
const (
	ConfigAuthTypeDigest = "digest"
	ConfigAuthTypeBearer = "bearer"
)

Variables

View Source
var (
	ErrBearerAuthInvalid     = errors.New("bearer auth invalid")
	ErrBearerAuthUnavailable = errors.New("bearer auth unavailable")
)
View Source
var (
	DirectionIn  = "IN"
	DirectionOut = "OUT"
)
View Source
var (
	BridgeCache = sync.Map{}
)
View Source
var (
	ErrRegistryDoesNotExist = errors.New("registry does not exist")
)

Functions

func AudioTestFile

func AudioTestFile(name string) string

func Bootstrap

func Bootstrap(ctx context.Context, conf Config, envConf EnvConfig)

func CacheDumpBridges

func CacheDumpBridges(f io.Writer) error

func ConfigLoad

func ConfigLoad(r io.Reader, c *Config) error

func ConfigLoadYamlFile

func ConfigLoadYamlFile(filename string, c *Config) error

func EnvConfigLoad

func EnvConfigLoad(c *EnvConfig) error

func NodeID

func NodeID() string

func ParseSIPTrace

func ParseSIPTrace(trace *SIPTrace, transport string, laddr string, raddr string, sipmsg []byte)

func SIPResponseReason

func SIPResponseReason(code int) string

SIPResponseReason returns the reason phrase associated with the SIP response code.

func SIPTraceDebug

func SIPTraceDebug(transport string, laddr string, raddr string, sipmsg []byte, rw int)

func SetNodeID

func SetNodeID(id string)

Types

type AudioMediaStack

type AudioMediaStack interface {
	AudioStereoRecordingCreate(*os.File) (diago.AudioStereoRecordingWav, error)
	SetAudioReader(io.Reader)
	SetAudioWriter(io.Writer)
}

type AuthorizerDigest

type AuthorizerDigest struct {
	// contains filtered or unexported fields
}

func NewAuthorizerDigest

func NewAuthorizerDigest(userpass map[string]string) *AuthorizerDigest

func (*AuthorizerDigest) Authorize

func (a *AuthorizerDigest) Authorize(inDialog *diago.DialogServerSession) (authorized bool)

type BridgeData

type BridgeData struct {
	ID      string
	NodeID  string
	Dialogs []string
}

type CDR

type CDR struct {
	Direction        string           `json:"direction"`
	CallID           string           `json:"callId"`
	OriginatorCallID string           `json:"originatorCallId"`
	StartTime        time.Time        `json:"startTime"`
	Duration         time.Duration    `json:"duration"`
	CallerID         string           `json:"callerId"`
	CalleeID         string           `json:"calleeId"`
	Bill             float64          `json:"bill"`
	Disposition      string           `json:"disposition"`
	MediaStats       DialogMediaStats `json:"mediaStats"`
	MES              float64          `json:"mes"` // Media Experience Score
	RecordingID      string           `json:"recordingId"`
	Bridged          bool             `json:"bridged"`

	StartTimeFormated string `json:"startTimeFormatted"`
}

type CDRMemoryStorage

type CDRMemoryStorage struct {
	// contains filtered or unexported fields
}

func NewCDRMemoryStorage

func NewCDRMemoryStorage() *CDRMemoryStorage

func (*CDRMemoryStorage) CDRRead

func (s *CDRMemoryStorage) CDRRead(ctx context.Context, buf []CDR, opts CDRReadOptions) (n int, err error)

func (*CDRMemoryStorage) CDRWrite

func (s *CDRMemoryStorage) CDRWrite(ctx context.Context, cdr CDR) error

type CDRPiper

type CDRPiper struct {
	CDRStorage
	Pipe chan CDR
}

func NewCDRPiper

func NewCDRPiper() *CDRPiper

func (*CDRPiper) CDRWrite

func (s *CDRPiper) CDRWrite(ctx context.Context, cdr CDR) error

type CDRReadOptions

type CDRReadOptions struct {
	Offset           int
	FromTime         time.Time
	ToTime           time.Time
	From             string
	To               string
	CallID           string
	OriginatorCallID string
	Mes              float64
}

type CDRStorage

type CDRStorage interface {
	CDRWrite(ctx context.Context, cdr CDR) error
	CDRRead(ctx context.Context, buf []CDR, opts CDRReadOptions) (n int, err error)
}

type CallContext

type CallContext struct {
	*PBX
	// contains filtered or unexported fields
}

func (*CallContext) AnswerWebrtc

func (cx *CallContext) AnswerWebrtc(inDialog *diago.DialogServerSession)

func (*CallContext) BridgeCall

func (cx *CallContext) BridgeCall(inDialog *diago.DialogServerSession)

func (*CallContext) ListenRTPSession

func (cx *CallContext) ListenRTPSession(rtpSess *media.RTPSession, stats *DialogMediaStats)

func (*CallContext) OnInboundRTPSession

func (cx *CallContext) OnInboundRTPSession(rtpSess *media.RTPSession)

func (*CallContext) OnOutboundRTPSession

func (cx *CallContext) OnOutboundRTPSession(rtpSess *media.RTPSession)

func (*CallContext) Playback

func (cx *CallContext) Playback(inDialog *diago.DialogServerSession)

func (*CallContext) PlaybackWebrtc

func (cx *CallContext) PlaybackWebrtc(inDialog *diago.DialogServerSession)

type Config

type Config struct {
	Version    string                     `yaml:"version"`
	Transports map[string]ConfigTransport `yaml:"transports"`
	Endpoints  map[string]ConfigEndpoint  `yaml:"endpoints"`
	Routes     map[string][]ConfigRoute   `yaml:"routes"`
	// contains filtered or unexported fields
}

Struct for the full YAML file

func (*Config) Validate

func (c *Config) Validate() error

type ConfigAOR

type ConfigAOR struct {
	URI      string     `yaml:"uri"`
	Protocol string     `yaml:"protocol"`
	Auth     ConfigAuth `yaml:"auth"`
}

Struct for AOR (Address of Record)

type ConfigAuth

type ConfigAuth struct {
	Type     string `yaml:"type"`
	Username string `yaml:"username"`
	Password string `yaml:"password"`
}

Struct for Auth details

func (ConfigAuth) AuthType

func (a ConfigAuth) AuthType() string

type ConfigEndpoint

type ConfigEndpoint struct {
	Name  string      `yaml:"name"`
	Match ConfigMatch `yaml:"match"`
	Auth  ConfigAuth  `yaml:"auth,omitempty"`
	URI   string      `yaml:"uri"`
	Route string      `yaml:"route"`

	// AOR         ConfigAOR   `yaml:"aor,omitempty"`
	// MatchNext   string `yaml:"match_next,omitempty"`
	TransportID string              `yaml:"transport,omitempty"`
	Media       ConfigEndpointMedia `yaml:"media"`
	ContactHDR  string              `yaml:"contact_header"`
	// contains filtered or unexported fields
}

Struct for each Endpoint

type ConfigEndpointMedia

type ConfigEndpointMedia struct {
	Type string `yaml:"type"`
}

type ConfigMatch

type ConfigMatch struct {
	Type      string   `yaml:"type"`
	Values    []string `yaml:"values,omitempty"`
	Transport string   `yaml:"transport,omitempty"`
}

Struct for Match section in each endpoint

type ConfigRecordings

type ConfigRecordings struct {
	Path string `yaml:"path,omitempty"`
}

type ConfigRoute

type ConfigRoute struct {
	ID             string              `yaml:"id"`
	EndpointName   string              `yaml:"endpoint"`
	Fallback       ConfigRouteFallback `yaml:"fallback"`
	Match          string              `yaml:"match"`
	StripPrefix    string              `yaml:"strip_prefix"`
	UseRegistry    bool                `yaml:"use_registry"`
	Recording      bool                `yaml:"recording"`
	Hangup         ConfigRouteHangup   `yaml:"hangup"`
	SipHeaders     map[string]string   `yaml:"sip_headers"`
	SipHeadersPass []string            `yaml:"sip_headers_pass"`
}

type ConfigRouteFallback

type ConfigRouteFallback struct {
	Enabled          bool     `yaml:"enabled"`
	Endpoints        []string `yaml:"endpoints"`
	FallbacksCodes   []int    `yaml:"codes"`
	FallbacksTimeout bool     `yaml:"timeout"`
}

type ConfigRouteHangup

type ConfigRouteHangup struct {
	Code   int    `yaml:"code"`
	Reason string `yaml:"reason"`
}

type ConfigTransport

type ConfigTransport struct {
	Transport       string `yaml:"transport"`
	Bind            string `yaml:"bind"`
	Port            int    `yaml:"port"`
	ExternalHost    string `yaml:"external_host"`
	ExternalPort    int    `yaml:"external_port"`
	ExternalMediaIP string `yaml:"external_media_ip"`
	RewriteContact  bool   `yaml:"rewrite_contact"`
}

Struct for Transports

type DialogCacheFile

type DialogCacheFile struct {
	NodeID string
	// contains filtered or unexported fields
}

func NewDialogCacheFile

func NewDialogCacheFile(nodeID string) *DialogCacheFile

func (*DialogCacheFile) Close

func (c *DialogCacheFile) Close()

func (*DialogCacheFile) DeleteDialog

func (c *DialogCacheFile) DeleteDialog(ctx context.Context, id string) error

func (*DialogCacheFile) DeleteDialogNode

func (c *DialogCacheFile) DeleteDialogNode(ctx context.Context, id string, nodeID string) error

TODO

func (*DialogCacheFile) Init

func (c *DialogCacheFile) Init() error

func (*DialogCacheFile) LoadDialog

func (c *DialogCacheFile) LoadDialog(ctx context.Context, id string) (DialogData, error)

func (*DialogCacheFile) LoadDialogs

func (c *DialogCacheFile) LoadDialogs(ctx context.Context, nodeID string) ([]DialogData, error)

func (*DialogCacheFile) StoreDialog

func (c *DialogCacheFile) StoreDialog(ctx context.Context, data DialogData) error

type DialogData

type DialogData struct {
	ID                string
	NodeID            string
	Direction         uint8 // 0: Server, 1:Client
	InviteRequestData string
	Dialplan          string
}

func NewDialogData

func NewDialogData(v *sipgo.Dialog, direction uint8) DialogData

type DialogExternalCache

type DialogExternalCache interface {
	StoreDialog(ctx context.Context, data DialogData) error
	LoadDialog(ctx context.Context, id string) (DialogData, error)
	DeleteDialog(ctx context.Context, id string) error
	DeleteDialogNode(ctx context.Context, id string, nodeId string) error
	LoadDialogs(ctx context.Context, nodeID string) ([]DialogData, error)
}

type DialogMediaStats

type DialogMediaStats struct {
	RTTMax            time.Duration `json:"rttMax"`
	RTTMin            time.Duration `json:"rttMin"`
	PacketsReadCount  uint64        `json:"packetsReadCount"`
	PacketsWriteCount uint64        `json:"packetsWriteCount"`
	PacketsReadLost   uint32        `json:"packetsReadLost"`
	PacketsWriteLost  uint32        `json:"packetsWriteLost"`
	MaxJitter         time.Duration `json:"maxJitter"`
}

type DialogRateLimiterIncoming

type DialogRateLimiterIncoming struct {
	DialogMax int64
	DialogRPS int64

	RateLimiterIn
}

type DialogRateLimiterOutgoing

type DialogRateLimiterOutgoing struct {
	DialogRPS int64

	RateLimiterOut
}

type EnvConfig

type EnvConfig struct {
	// Internal
	Cluster     bool `env:"GOPBX_CLUSTER"`
	TestMode    bool `env:"TEST_MODE"`
	SIPDebug    bool `env:"SIP_DEBUG" envDefault:"false"`
	SIPCDRTrace bool `env:"SIP_CDR_TRACE" envDefault:"true"`
	RTPDebug    bool `env:"RTP_DEBUG" envDefault:"false"`
	RTCPDebug   bool `env:"RTCP_DEBUG" envDefault:"false"`

	OutboundDialUri  string `env:"OUTBOUND_DIAL_URI" envDefault:""`
	ConfFile         string `env:"CONF_FILE" envDefault:"diagox.yaml"`
	CDREnable        bool   `env:"CDR_ENABLE" envDefault:"true"`
	RecordingsPath   string `env:"RECORDINGS_PATH" envDefault:"recordings"`
	FrontendEnable   bool   `env:"FRONTEND_ENABLE" envDefault:"false"`
	FrontendDevMode  bool   `env:"FRONTEND_DEV_MODE" envDefault:"false"`
	HTTPAddr         string `env:"HTTP_ADDR" envDefault:":6060"`
	HTTPDebug        bool   `env:"HTTP_DEBUG" envDefault:"false"`
	MediaCodecs      string `env:"MEDIA_CODECS" envDefault:""`
	WebrtcICEServers string `env:"WEBRTC_ICE_SERVERS" envDefault:""`
	WebrtcSTUN       WebrtcSTUNConfig
	Redis            RedisConfig
	Mysql            MysqlConfig
	Postgres         PostgresConfig
	// SIP global transport overrides
	// if you have dedicated interface like POD ip, set SIP_BIND_IP
	SIPBindIP          string `env:"SIP_BIND_IP" envDefault:""`
	SIPExternalHost    string `env:"SIP_EXTERNAL_HOST" envDefault:""`
	SIPExternalMediaIP string `env:"SIP_EXTERNAL_MEDIA_IP" envDefault:""`
	// SIP_HOSTNAME identifies that message are matching this hostname like REGISTER
	SIPHostname           string `env:"SIP_HOSTNAME" envDefault:""`
	RateLimiterIn         RateLimiterIncomingConfig
	RateLimiterOut        RateLimiterOutgoingConfig
	SIPRegisterBearerAuth SIPRegisterBearerAuthConfig

	// TLS
	ServerTLSKeyPath string `env:"SERVER_TLS_KEY_PATH" envDefault:""`
	ServerTLSCrtPath string `env:"SERVER_TLS_CRT_PATH" envDefault:""`
	ServerTLSKey     string `env:"SERVER_TLS_KEY" envDefault:""` // Base64 encoded key
	ServerTLSCrt     string `env:"SERVER_TLS_CRT" envDefault:""` // Base64 encoded CRT

	// Flow RPC
	FlowRPCAddr string `env:"FLOW_RPC_HTTP_ADDR" envDefault:":6000"`
}

type FlowConnection

type FlowConnection struct {
	// contains filtered or unexported fields
}

type FlowDialogChan

type FlowDialogChan struct {
	// contains filtered or unexported fields
}

type FlowRPC

type FlowRPC struct {
	Config Config
	// contains filtered or unexported fields
}

func NewFlowRPC

func NewFlowRPC(conf Config) *FlowRPC

func (*FlowRPC) NewServerDialog

func (rpc *FlowRPC) NewServerDialog(ctx context.Context, toEndpointId string, d *diago.DialogServerSession, next *ConfigEndpoint) error

func (*FlowRPC) Serve

func (rpc *FlowRPC) Serve(addr string) error

func (*FlowRPC) ServeBackground

func (rpc *FlowRPC) ServeBackground(addr string)

type FlowRequest

type FlowRequest struct {
	ID   string          `json:"id"`
	DID  string          `json:"did"`
	OP   string          `json:"op"`
	Data json.RawMessage `json:"data"`
	// contains filtered or unexported fields
}

type FlowResponse

type FlowResponse struct {
	ID     string          `json:"id"`
	DID    string          `json:"did"` // dialog ID
	Code   int             `json:"code"`
	Reason string          `json:"reason"`
	Data   json.RawMessage `json:"data"`
}

type Handler

type Handler struct {
	CdrStore CDRStorage

	D *diago.Diago

	SIPtracer SIPTracer
	// contains filtered or unexported fields
}

type MysqlConfig

type MysqlConfig struct {
	User     string `env:"MYSQL_USER" envDefault:"diagox"`
	Password string `env:"MYSQL_PASSWORD"`
	Database string `env:"MYSQL_DATABASE" envDefault:"diagox"`
	Host     string `env:"MYSQL_HOST" envDefault:""`
}

type PBX

type PBX struct {
	// contains filtered or unexported fields
}

func NewPBX

func NewPBX(envConf EnvConfig, conf Config) *PBX

func NewPBXMemory

func NewPBXMemory(envConf EnvConfig, conf Config) *PBX

func (*PBX) ApplyProviders

func (p *PBX) ApplyProviders(providers Providers)

func (*PBX) DialogCache

func (p *PBX) DialogCache() DialogExternalCache

func (*PBX) ExternalMedia

func (pbx *PBX) ExternalMedia(inDialog *diago.DialogServerSession)

func (*PBX) Init

func (pbx *PBX) Init(ctx context.Context, conf Config) error

func (*PBX) ReInviteDialogs

func (pbx *PBX) ReInviteDialogs(ctx context.Context, dialogs []DialogData, bridges []BridgeData) error

func (*PBX) Run

func (pbx *PBX) Run(ctx context.Context) error

func (*PBX) SIPTracer

func (p *PBX) SIPTracer() SIPTracer

func (*PBX) Serve

func (pbx *PBX) Serve(ctx context.Context) error

func (*PBX) ServeBackground

func (pbx *PBX) ServeBackground(ctx context.Context) error

func (*PBX) WebrtcBridge

func (pbx *PBX) WebrtcBridge(inDialog *diago.DialogServerSession) error

type PostgresConfig

type PostgresConfig struct {
	User     string `env:"POSTGRES_USER" envDefault:"diagox"`
	Password string `env:"POSTGRES_PASSWORD"`
	Database string `env:"POSTGRES_DATABASE" envDefault:"diagox"`
	Host     string `env:"POSTGRES_HOST" envDefault:""`
}

type Providers

type Providers struct {
	CDRStore  CDRStorage
	Registry  RegistryStore
	SIPTracer SIPTracer
	Cache     DialogExternalCache
	RateIn    *DialogRateLimiterIncoming
	RateOut   *DialogRateLimiterOutgoing
	Cleanup   []func()
}

func NewDefaultProviders

func NewDefaultProviders(envConf EnvConfig) Providers

type RateLimiterAtomic

type RateLimiterAtomic struct {
	Max int64
	RPS int64
	// contains filtered or unexported fields
}

func (*RateLimiterAtomic) Block

func (r *RateLimiterAtomic) Block(log *slog.Logger, ctx context.Context) error

Block based on current RPS limit It absorbs (blocks) until RPS drops down

func (*RateLimiterAtomic) DialogActiveDec

func (r *RateLimiterAtomic) DialogActiveDec()

func (*RateLimiterAtomic) DialogActiveLimit

func (r *RateLimiterAtomic) DialogActiveLimit() bool

Checks Dialog RPS

func (*RateLimiterAtomic) DialogRPSLimit

func (r *RateLimiterAtomic) DialogRPSLimit() bool

Checks Dialog RPS

type RateLimiterIn

type RateLimiterIn interface {
	DialogActiveLimit() bool
	DialogActiveDec()
	DialogRPSLimit() bool
}

type RateLimiterIncomingConfig

type RateLimiterIncomingConfig struct {
	Enabled   bool  `env:"RATE_LIMITER_IN_ENABLED" envDefault:"false"`
	DialogRPS int64 `env:"RATE_LIMITER_IN_DIALOG_RPS"`
	DialogMax int64 `env:"RATE_LIMITER_IN_DIALOG_MAX"`
}

type RateLimiterOut

type RateLimiterOut interface {
	Block(log *slog.Logger, ctx context.Context) error
	DialogRPSLimit() bool
}

type RateLimiterOutgoingConfig

type RateLimiterOutgoingConfig struct {
	Enabled   bool  `env:"RATE_LIMITER_OUT_ENABLED" envDefault:"false"`
	DialogRPS int64 `env:"RATE_LIMITER_OUT_DIALOG_RPS"`
}

type RedisConfig

type RedisConfig struct {
	Addr              string `env:"REDIS_ADDR" envDefault:""` // Addr holds the address to connect with Redis. If multiple addresses are provided seperated by comma, then redis cluster is being used
	Username          string `env:"REDIS_USERNAME" envDefault:""`
	Password          string `env:"REDIS_PASSWORD" envDefault:""`
	CacheEnabled      bool   `env:"REDIS_CACHE" envDefault:"true"`
	SentinelMasterSet string `env:"REDIS_SENTINEL_MASTER_SET" envDefault:""`
	CacheConnSizeMB   int    `env:"REDIS_CACHE_CONN_SIZE_MB" envDefault:"32"`
}

type RegisterBinding

type RegisterBinding struct {
	Aor        sip.Uri
	CallID     string
	Contacts   []sip.Uri
	Expiry     time.Duration
	TenantID   string // TODO should be mapped from tenant_host to id
	SourceAddr string
	Transport  string
}

type Registrar

type Registrar struct {
	Hostname    string
	Registry    RegistryStore
	DigestStore UserDigestAuthStore
	BearerStore UserBearerAuthStore
	// contains filtered or unexported fields
}

func NewRegistrar

func NewRegistrar(hostname string, registry RegistryStore, digestStore UserDigestAuthStore, bearerStore UserBearerAuthStore) *Registrar

func (*Registrar) RegisterHandler

func (p *Registrar) RegisterHandler(req *sip.Request, tx sip.ServerTransaction)

type RegistryMemory

type RegistryMemory struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

func NewRegistryMemory

func NewRegistryMemory() *RegistryMemory

func (*RegistryMemory) RegisterBindingContactDelete

func (r *RegistryMemory) RegisterBindingContactDelete(id string, contact sip.Uri) error

func (*RegistryMemory) RegisterBindingDelete

func (r *RegistryMemory) RegisterBindingDelete(id string) error

func (*RegistryMemory) RegisterBindingGet

func (r *RegistryMemory) RegisterBindingGet(id string) (RegisterBinding, error)

func (*RegistryMemory) RegisterBindingSet

func (r *RegistryMemory) RegisterBindingSet(id string, rec RegisterBinding) error

type RegistryStore

type RegistryStore interface {
	// TODO add context
	RegisterBindingSet(id string, r RegisterBinding) error
	RegisterBindingDelete(id string) error
	RegisterBindingContactDelete(id string, contactAddress sip.Uri) error
	RegisterBindingGet(id string) (RegisterBinding, error)
}

type Router

type Router struct {
	// contains filtered or unexported fields
}

func (*Router) MatchEndpoint

func (r *Router) MatchEndpoint(req *sip.Request, end *ConfigEndpoint) bool

func (*Router) MatchIncomingRoute

func (r *Router) MatchIncomingRoute(req *sip.Request, routeID string, route *ConfigRoute) bool

func (*Router) MatchOutgoingRouteEndpoint

func (r *Router) MatchOutgoingRouteEndpoint(req *sip.Request, route *ConfigRoute, end *ConfigEndpoint) bool

func (*Router) Route

func (r *Router) Route(fromUser string, uri *sip.Uri, auth *diago.DigestAuth) error

func (*Router) RouteDialog

func (r *Router) RouteDialog(dialog *diago.DialogServerSession, uri *sip.Uri, auth *diago.DigestAuth) error

Routes call and fils URI

type SIPRegisterBearerAuthConfig

type SIPRegisterBearerAuthConfig struct {
	URL           string        `env:"SIP_REGISTER_BEARER_AUTH_URL" envDefault:""`
	Timeout       time.Duration `env:"SIP_REGISTER_BEARER_AUTH_TIMEOUT"`
	IdentityField string        `env:"SIP_REGISTER_BEARER_AUTH_IDENTITY_FIELD"`
	ActiveField   string        `env:"SIP_REGISTER_BEARER_AUTH_ACTIVE_FIELD"`
	Header        string        `env:"SIP_REGISTER_BEARER_AUTH_HEADER" envDefault:""`
}

type SIPTrace

type SIPTrace struct {
	Created          time.Time
	RW               int // 0 read 1 write
	Transport        string
	Laddr            string
	Raddr            string
	CallID           string
	OriginatorCallID string
	Msg              string
}

type SIPTracer

type SIPTracer interface {
	sip.SIPTracer
	SIPTraceFind(callID string, f func(m SIPTrace))
}

type SipTracerMemoryStorage

type SipTracerMemoryStorage struct {
	// contains filtered or unexported fields
}

func NewSipTracerMemoryStorage

func NewSipTracerMemoryStorage() *SipTracerMemoryStorage

func (*SipTracerMemoryStorage) SIPTraceFind

func (s *SipTracerMemoryStorage) SIPTraceFind(callID string, f func(m SIPTrace))

func (*SipTracerMemoryStorage) SIPTraceRead

func (s *SipTracerMemoryStorage) SIPTraceRead(transport string, laddr string, raddr string, sipmsg []byte)

func (*SipTracerMemoryStorage) SIPTraceWrite

func (s *SipTracerMemoryStorage) SIPTraceWrite(transport string, laddr string, raddr string, sipmsg []byte)

type UserAuthStoreBearerHTTP

type UserAuthStoreBearerHTTP struct {
	HTTPClient *http.Client
	Config     SIPRegisterBearerAuthConfig
}

func (*UserAuthStoreBearerHTTP) UserAuthenticateBearer

func (s *UserAuthStoreBearerHTTP) UserAuthenticateBearer(ctx context.Context, auth UserBearerAuth) error

type UserAuthStoreMemory

type UserAuthStoreMemory struct {
	// contains filtered or unexported fields
}

func NewUserAuthStoreMemory

func NewUserAuthStoreMemory() *UserAuthStoreMemory

func (*UserAuthStoreMemory) UserAuthAdd

func (s *UserAuthStoreMemory) UserAuthAdd(user string, auth diago.DigestAuth) error

func (*UserAuthStoreMemory) UserReadDigestAuth

func (s *UserAuthStoreMemory) UserReadDigestAuth(user string, auth *diago.DigestAuth) error

type UserBearerAuth

type UserBearerAuth struct {
	User   string
	Token  string
	Method string
}

type UserBearerAuthStore

type UserBearerAuthStore interface {
	UserAuthenticateBearer(ctx context.Context, auth UserBearerAuth) error
}

type UserDigestAuthStore

type UserDigestAuthStore interface {
	// TODO extend with tenant domain
	UserReadDigestAuth(user string, auth *diago.DigestAuth) error
}

type WebrtcSTUNConfig

type WebrtcSTUNConfig struct {
	Enabled  bool   `env:"WEBRTC_STUN_ENABLED" envDefault:"false"`
	BindIP   string `env:"WEBRTC_STUN_BIND_IP" envDefault:"0.0.0.0"`
	Port     int    `env:"WEBRTC_STUN_PORT" envDefault:"3478"`
	PublicIP string `env:"WEBRTC_STUN_PUBLIC_IP" envDefault:""`
	Realm    string `env:"WEBRTC_STUN_REALM" envDefault:"diagox"`
	Username string `env:"WEBRTC_STUN_USERNAME" envDefault:""`
	Password string `env:"WEBRTC_STUN_PASSWORD" envDefault:""`
}

Directories

Path Synopsis
cmd
diagox command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL
⌂ 换网址