Skip to content

Commit

Permalink
Response RTP Start/End Ports in config
Browse files Browse the repository at this point in the history
  • Loading branch information
Sean-Der committed Dec 4, 2023
1 parent 38500e6 commit ff189f7
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 16 deletions.
2 changes: 1 addition & 1 deletion pkg/sip/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ func (c *Client) UpdateSIPParticipant(ctx context.Context, req *rpc.InternalUpda
}, lkRoomConfig{
roomName: req.RoomName,
identity: req.ParticipantIdentity,
})
}, c.conf)
if err != nil {
return nil, err
}
Expand Down
52 changes: 52 additions & 0 deletions pkg/sip/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,18 @@ import (
"encoding/json"
"fmt"
"io"
"math/rand"
"net"
"net/http"
"time"
)

var source *rand.Rand

func init() {
source = rand.New(rand.NewSource(time.Now().UnixNano()))
}

func getPublicIP() (string, error) {
req, err := http.Get("http://ip-api.com/json/")
if err != nil {
Expand Down Expand Up @@ -76,3 +84,47 @@ func getLocalIP() (string, error) {

return "", fmt.Errorf("No local interface found")
}

var listenErr = fmt.Errorf("Failed to listen on UDP Port")

func listenUDPInPortRange(portMin, portMax int, IP net.IP) (*net.UDPConn, error) {
if portMin == 0 && portMax == 0 {
return net.ListenUDP("udp", &net.UDPAddr{
IP: IP,
Port: 0,
})
}

i := portMin
if i == 0 {
i = 1
}

j := portMax
if j == 0 {
j = 0xFFFF
}

if i > j {
return nil, listenErr
}

portStart := source.Intn(portMax-portMin+1) + portMin
portCurrent := portStart

for {
c, e := net.ListenUDP("udp", &net.UDPAddr{IP: IP, Port: portCurrent})
if e == nil {
return c, nil
}

portCurrent++
if portCurrent > j {
portCurrent = i
}
if portCurrent == portStart {
break
}
}
return nil, listenErr
}
12 changes: 7 additions & 5 deletions pkg/sip/inbound.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/icholy/digest"
"github.com/pion/sdp/v2"

"github.com/livekit/sip/pkg/config"
"github.com/livekit/sip/pkg/media"
"github.com/livekit/sip/pkg/media/rtp"
"github.com/livekit/sip/pkg/media/ulaw"
Expand Down Expand Up @@ -121,7 +122,7 @@ func (s *Server) onInvite(req *sip.Request, tx sip.ServerTransaction) {
return
}
call := s.newInboundCall(tag, from, to, src)
call.handleInvite(req, tx)
call.handleInvite(req, tx, s.conf)
}

type inboundCall struct {
Expand Down Expand Up @@ -150,7 +151,7 @@ func (s *Server) newInboundCall(tag string, from *sip.FromHeader, to *sip.ToHead
return c
}

func (c *inboundCall) handleInvite(req *sip.Request, tx sip.ServerTransaction) {
func (c *inboundCall) handleInvite(req *sip.Request, tx sip.ServerTransaction, conf *config.Config) {
// Send initial request. In the best case scenario, we will immediately get a room name to join.
// Otherwise, we could even learn that this number is not allowed and reject the call, or ask for pin if required.
roomName, identity, requirePin, rejectInvite := c.s.dispatchRuleHandler(c.from.Address.User, c.to.Address.User, c.src, "", false)
Expand All @@ -160,7 +161,8 @@ func (c *inboundCall) handleInvite(req *sip.Request, tx sip.ServerTransaction) {
}

// We need to start media first, otherwise we won't be able to send audio prompts to the caller, or receive DTMF.
answerData, err := c.runMediaConn(req.Body())
answerData, err := c.runMediaConn(req.Body(), conf)

if err != nil {
sipErrorResponse(tx, req)
return
Expand All @@ -185,10 +187,10 @@ func (c *inboundCall) handleInvite(req *sip.Request, tx sip.ServerTransaction) {
}
}

func (c *inboundCall) runMediaConn(offerData []byte) (answerData []byte, _ error) {
func (c *inboundCall) runMediaConn(offerData []byte, conf *config.Config) (answerData []byte, _ error) {
conn := NewMediaConn()
conn.OnRTP(c)
if err := conn.Start("0.0.0.0"); err != nil {
if err := conn.Start(conf.RTPPort.Start, conf.RTPPort.End, "0.0.0.0"); err != nil {
return nil, err
}
c.rtpConn = conn
Expand Down
9 changes: 4 additions & 5 deletions pkg/sip/media_sip.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,14 @@ func (c *MediaConn) Close() error {
return nil
}

func (c *MediaConn) Start(listenAddr string) error {
func (c *MediaConn) Start(portMin, portMax int, listenAddr string) error {
if listenAddr == "" {
listenAddr = "0.0.0.0"
}

var err error
c.conn, err = net.ListenUDP("udp", &net.UDPAddr{
IP: net.ParseIP(listenAddr),
Port: 0,
})
c.conn, err = listenUDPInPortRange(portMin, portMax, net.ParseIP(listenAddr))

if err != nil {
return err
}
Expand Down
13 changes: 8 additions & 5 deletions pkg/sip/outbound.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/icholy/digest"
"github.com/livekit/protocol/logger"

"github.com/livekit/sip/pkg/config"
"github.com/livekit/sip/pkg/media"
"github.com/livekit/sip/pkg/media/rtp"
"github.com/livekit/sip/pkg/media/ulaw"
Expand Down Expand Up @@ -112,7 +113,7 @@ func (c *outboundCall) close() {
// FIXME: remove call from the client map?
}

func (c *outboundCall) Update(ctx context.Context, sipNew sipOutboundConfig, lkNew lkRoomConfig) error {
func (c *outboundCall) Update(ctx context.Context, sipNew sipOutboundConfig, lkNew lkRoomConfig, conf *config.Config) error {
c.mu.RLock()
sipCur, lkCur := c.sipCur, c.lkCur
c.mu.RUnlock()
Expand All @@ -132,7 +133,7 @@ func (c *outboundCall) Update(ctx context.Context, sipNew sipOutboundConfig, lkN
c.close()
return nil
}
if err := c.startMedia(); err != nil {
if err := c.startMedia(conf); err != nil {
c.close()
return fmt.Errorf("start media failed: %w", err)
}
Expand All @@ -150,11 +151,11 @@ func (c *outboundCall) Update(ctx context.Context, sipNew sipOutboundConfig, lkN
return nil
}

func (c *outboundCall) startMedia() error {
func (c *outboundCall) startMedia(conf *config.Config) error {
if c.mediaRunning {
return nil
}
if err := c.rtpConn.Start("0.0.0.0"); err != nil {
if err := c.rtpConn.Start(conf.RTPPort.Start, conf.RTPPort.End, "0.0.0.0"); err != nil {
return err
}
c.mediaRunning = true
Expand Down Expand Up @@ -239,7 +240,9 @@ func sipResponse(tx sip.ClientTransaction) (*sip.Response, error) {

func (c *outboundCall) stopSIP() {
if c.sipInviteReq != nil {
c.sipBye()
if err := c.sipBye(); err != nil {
logger.Errorw("SIP bye failed", err)
}
}
c.sipInviteReq = nil
c.sipInviteResp = nil
Expand Down

0 comments on commit ff189f7

Please sign in to comment.