Skip to content

Commit

Permalink
holepunch without double channel opening when connecting quickly
Browse files Browse the repository at this point in the history
  • Loading branch information
davidded committed Dec 18, 2023
1 parent c61d929 commit 082e50f
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 2 deletions.
12 changes: 12 additions & 0 deletions src/sccp_channel.c
Expand Up @@ -775,6 +775,17 @@ void sccp_channel_StatisticsRequest(constChannelPtr channel)
d->protocol->sendConnectionStatisticsReq(d, channel, SKINNY_STATSPROCESSING_CLEAR);
}



/*
* \brief returns true if a hole punch process has been started but not finished yet. necessary to decide behaviour in call logic to avoid double channel opening.
*/
boolean_t sccp_channel_holePunchPending(constChannelPtr c)
{
pbx_assert(c != NULL && c->privateData);
return c->privateData->firewall_holepunch;
}

/*
* \brief a simple way to punch a whole in the firewall by sending a short burst of packets during progress
* transmission will be stopped again as soon as the first packet has been received from the device in astwrap_rtp_read
Expand All @@ -798,6 +809,7 @@ void sccp_channel_startHolePunch(constChannelPtr c)
//}
}

// When the keepChannelOpen parameter is true, then we don't do anything since we assume either everything should stay open or will be opened by following code (i.e. before a connect)
boolean_t sccp_channel_finishHolePunch(constChannelPtr c, boolean_t keepChannelOpen)
{
pbx_assert(c != NULL && c->privateData);
Expand Down
1 change: 1 addition & 0 deletions src/sccp_channel.h
Expand Up @@ -146,6 +146,7 @@ SCCP_API void SCCP_CALL sccp_channel_set_calledparty(constChannelPtr channel, co
SCCP_API boolean_t SCCP_CALL sccp_channel_set_originalCalledparty(constChannelPtr channel, char * name, char * number);
SCCP_API void SCCP_CALL sccp_channel_set_calleridPresentation(constChannelPtr channel, sccp_callerid_presentation_t presentation);
SCCP_API boolean_t SCCP_CALL sccp_channel_finishHolePunch(constChannelPtr channel, boolean_t keepChannelOpen);
SCCP_API boolean_t SCCP_CALL sccp_channel_holePunchPending(constChannelPtr c);
SCCP_API void SCCP_CALL sccp_channel_startHolePunch(constChannelPtr c);
SCCP_API boolean_t __PURE__ SCCP_CALL sccp_channel_isAnswering(constChannelPtr c);
SCCP_API void SCCP_CALL sccp_channel_openReceiveChannel(constChannelPtr channel);
Expand Down
10 changes: 8 additions & 2 deletions src/sccp_indicate.c
Expand Up @@ -278,16 +278,22 @@ void __sccp_indicate (constDevicePtr maybe_device, channelPtr c, const sccp_chan
// media transmission. Discuss the semantics of the holepunch. How often do we need to do this, when can the
// RTP ports change? It could be a more appropriate time to mark the hole as non-punched as soon as the lifetime
// of RTP port validity changes and instead consider the hole-punch a one-time action while they are still valid.

// Opening the media transmission is not necessary if a hole punch has been started. Otherwise we would double open it.
// \todo Do we need to lock the channel here to make sure packet handling from pbx_impl does not break things here,
// or is locking done there already iirc?
if(!sccp_channel_holePunchPending(c))
sccp_rtp_setCallback(&c->rtp.audio, SCCP_RTP_RECEPTION, sccp_channel_startMediaTransmission);

if(c->calltype != SKINNY_CALLTYPE_INBOUND) {
if(d->nat >= SCCP_NAT_ON) {
// Since the channel is already connected, we can leave the audio open and don't need to close the sending side.
// This is also necessary to avoid that some of the phones (notably 79x1, 89xx) also close the receiving audio.
// \todo Check if this condition needs to be handled by two cases in the pbx_impl code for incoming packets.
// Or is this already handled by assuming the channel will be up and thus hole punching won't be handled any more?
sccp_channel_finishHolePunch(c, false);
sccp_channel_finishHolePunch(c, true);
}
}
sccp_rtp_setCallback(&c->rtp.audio, SCCP_RTP_RECEPTION, sccp_channel_startMediaTransmission);
if(!sccp_rtp_getState(&c->rtp.audio, SCCP_RTP_RECEPTION)) {
sccp_channel_openReceiveChannel(c);
} else if(!sccp_rtp_getState(&c->rtp.audio, SCCP_RTP_TRANSMISSION)) {
Expand Down

0 comments on commit 082e50f

Please sign in to comment.