@@ -50,7 +50,8 @@ std::mutex V24UDPPort::m_bufferMutex;
5050
5151/* Initializes a new instance of the V24UDPPort class. */
5252
53- V24UDPPort::V24UDPPort (uint32_t peerId, const std::string& address, uint16_t modemPort, uint16_t controlPort, bool useFSC, bool fscInitiator, bool debug) :
53+ V24UDPPort::V24UDPPort (uint32_t peerId, const std::string& address, uint16_t modemPort, uint16_t controlPort,
54+ uint16_t controlLocalPort, bool useFSC, bool fscInitiator, bool debug) :
5455 m_socket(nullptr ),
5556 m_localPort(modemPort),
5657 m_controlSocket(nullptr ),
@@ -60,8 +61,11 @@ V24UDPPort::V24UDPPort(uint32_t peerId, const std::string& address, uint16_t mod
6061 m_controlAddr(),
6162 m_addrLen(0U ),
6263 m_ctrlAddrLen(0U ),
63- m_remoteAddr(),
64- m_remoteAddrLen(0U ),
64+ m_ctrlLocalPort(controlLocalPort),
65+ m_remoteCtrlAddr(),
66+ m_remoteCtrlAddrLen(0U ),
67+ m_remoteRTPAddr(),
68+ m_remoteRTPAddrLen(0U ),
6569 m_buffer(2000U , " UDP Port Ring Buffer" ),
6670 m_fscInitiator(fscInitiator),
6771 m_timeoutTimer(1000U , 45U ),
@@ -83,15 +87,18 @@ V24UDPPort::V24UDPPort(uint32_t peerId, const std::string& address, uint16_t mod
8387 assert (modemPort > 0U );
8488
8589 if (controlPort > 0U && useFSC) {
86- m_controlSocket = new Socket (controlPort);
90+ if (controlLocalPort == 0U )
91+ controlLocalPort = controlPort;
92+
93+ m_controlSocket = new Socket (controlLocalPort);
8794 m_ctrlFrameQueue = new RawFrameQueue (m_controlSocket, m_debug);
8895
8996 if (udp::Socket::lookup (address, controlPort, m_controlAddr, m_ctrlAddrLen) != 0 )
9097 m_ctrlAddrLen = 0U ;
9198
9299 if (m_ctrlAddrLen > 0U ) {
93- m_remoteAddr = m_controlAddr;
94- m_remoteAddrLen = m_remoteAddrLen ;
100+ m_remoteCtrlAddr = m_controlAddr;
101+ m_remoteCtrlAddrLen = m_remoteCtrlAddrLen ;
95102
96103 std::string ctrlAddrStr = udp::Socket::address (m_controlAddr);
97104 LogWarning (LOG_HOST, " SECURITY: Remote modem expects V.24 control channel IP address; %s for remote modem control" , ctrlAddrStr.c_str ());
@@ -272,7 +279,7 @@ int V24UDPPort::write(const uint8_t* buffer, uint32_t length)
272279 if (m_debug)
273280 Utils::dump (1U , " !!! Tx Outgoing DFSI UDP" , buffer + 4U , length - 4U );
274281
275- bool written = m_socket->write (message, messageLen, m_addr, m_addrLen );
282+ bool written = m_socket->write (message, messageLen, m_remoteRTPAddr, m_remoteRTPAddrLen );
276283 if (written)
277284 return length;
278285 } else {
@@ -408,16 +415,24 @@ void* V24UDPPort::threadedCtrlNetworkRx(void* arg)
408415 network->m_socket = nullptr ;
409416 }
410417
411- network->m_localPort = vcBasePort;
412- network->createVCPort (vcBasePort);
418+ uint16_t remoteCtrlPort = Socket::port (req->address );
419+ network->m_remoteCtrlAddr = req->address ;
420+ network->m_remoteCtrlAddrLen = req->addrLen ;
421+
422+ // setup local RTP VC port (where we receive traffic)
423+ network->createVCPort (network->m_localPort );
413424 network->m_socket ->open (network->m_addr );
414425
426+ // setup remote RTP VC port (where we send traffic to)
427+ std::string remoteAddress = Socket::address (req->address );
428+ network->createRemoteVCPort (remoteAddress, vcBasePort);
429+
415430 network->m_fscState = CS_CONNECTED;
416431 network->m_reqConnectionTimer .stop ();
417432 network->m_heartbeatTimer .start ();
418433 network->m_timeoutTimer .start ();
419434
420- LogMessage (LOG_MODEM, " V.24 UDP, Established DFSI FSC Connection, vcBasePort = %u" , vcBasePort);
435+ LogMessage (LOG_MODEM, " V.24 UDP, Established DFSI FSC Connection, ctrlRemotePort = %u, vcLocalPort = %u, vcRemotePort = %u " , remoteCtrlPort, network-> m_localPort , vcBasePort);
421436 }
422437 break ;
423438
@@ -449,6 +464,10 @@ void* V24UDPPort::threadedCtrlNetworkRx(void* arg)
449464 LogError (LOG_MODEM, " V.24 UDP, unknown ACK opcode, ackMessageId = $%02X" , ackMessage->getAckMessageId ());
450465 break ;
451466 }
467+
468+ if (ackMessage->getResponseLength () > 0U && ackMessage->responseData != nullptr ) {
469+ delete[] ackMessage->responseData ; // FSCACK doesn't clean itself up...
470+ }
452471 }
453472 break ;
454473
@@ -478,30 +497,35 @@ void* V24UDPPort::threadedCtrlNetworkRx(void* arg)
478497 network->m_socket = nullptr ;
479498 }
480499
481- uint16_t vcPort = connMessage->getVCBasePort ();
500+ uint16_t vcBasePort = connMessage->getVCBasePort ();
482501 network->m_heartbeatInterval = connMessage->getHostHeartbeatPeriod ();
483502 if (network->m_heartbeatInterval > 30U )
484503 network->m_heartbeatInterval = 30U ;
485- network->m_localPort = vcPort;
486504
505+ uint16_t remoteCtrlPort = Socket::port (req->address );
506+ network->m_remoteCtrlAddr = req->address ;
507+ network->m_remoteCtrlAddrLen = req->addrLen ;
508+
509+ LogMessage (LOG_MODEM, " V.24 UDP, Incoming DFSI FSC Connection, ctrlRemotePort = %u, vcLocalPort = %u, vcRemotePort = %u, hostHBInterval = %u" , remoteCtrlPort, network->m_localPort , vcBasePort, connMessage->getHostHeartbeatPeriod ());
510+
511+ // setup local RTP VC port (where we receive traffic)
487512 network->createVCPort (network->m_localPort );
488513 network->m_socket ->open (network->m_addr );
489514
515+ // setup remote RTP VC port (where we send traffic to)
516+ std::string remoteAddress = Socket::address (req->address );
517+ network->createRemoteVCPort (remoteAddress, vcBasePort);
518+
490519 network->m_fscState = CS_CONNECTED;
491520 network->m_reqConnectionTimer .stop ();
492521
493- network->m_remoteAddr = req->address ;
494- network->m_remoteAddrLen = req->addrLen ;
495-
496522 if (connMessage->getHostHeartbeatPeriod () > 30U )
497523 LogWarning (LOG_MODEM, " V.24 UDP, DFSI FSC Connection, requested heartbeat of %u, reduce to 30 seconds or less" , connMessage->getHostHeartbeatPeriod ());
498524
499525 network->m_heartbeatTimer = Timer (1000U , network->m_heartbeatInterval );
500526 network->m_heartbeatTimer .start ();
501527 network->m_timeoutTimer .start ();
502528
503- LogMessage (LOG_MODEM, " V.24 UDP, Incoming DFSI FSC Connection, vcBasePort = %u, hostHBInterval = %u" , network->m_localPort , connMessage->getHostHeartbeatPeriod ());
504-
505529 // construct connect ACK response data
506530 uint8_t respData[3U ];
507531 ::memset (respData, 0x00U , 3U );
@@ -517,7 +541,8 @@ void* V24UDPPort::threadedCtrlNetworkRx(void* arg)
517541 ::memset (buffer, 0x00U , FSCACK::LENGTH + 3U );
518542 ackResp.encode (buffer);
519543
520- network->m_ctrlFrameQueue ->write (buffer, FSCACK::LENGTH + 3U , req->address , req->addrLen );
544+ if (network->m_ctrlFrameQueue ->write (buffer, FSCACK::LENGTH + 3U , req->address , req->addrLen ))
545+ LogMessage (LOG_MODEM, " V.24 UDP, Established DFSI FSC Connection, ctrlRemotePort = %u, vcLocalPort = %u, vcRemotePort = %u" , remoteCtrlPort, network->m_localPort , vcBasePort);
521546 }
522547 break ;
523548
@@ -676,7 +701,7 @@ void* V24UDPPort::threadedVCNetworkRx(void* arg)
676701 }
677702
678703 if (req->length > 0 ) {
679- if (udp::Socket::match (req->address , network->m_addr )) {
704+ if (udp::Socket::match (req->address , network->m_remoteRTPAddr )) {
680705 UInt8Array __reply = std::make_unique<uint8_t []>(req->length + 4U );
681706 uint8_t * reply = __reply.get ();
682707
@@ -705,7 +730,7 @@ void* V24UDPPort::threadedVCNetworkRx(void* arg)
705730 return nullptr ;
706731}
707732
708- /* Internal helper to setup the voice channel port. */
733+ /* Internal helper to setup the local voice channel port. */
709734
710735void V24UDPPort::createVCPort (uint16_t port)
711736{
@@ -716,7 +741,20 @@ void V24UDPPort::createVCPort(uint16_t port)
716741
717742 if (m_addrLen > 0U ) {
718743 std::string addrStr = udp::Socket::address (m_addr);
719- LogWarning (LOG_HOST, " SECURITY: Remote modem expects V.24 voice channel IP address; %s for remote modem control" , addrStr.c_str ());
744+ LogWarning (LOG_HOST, " SECURITY: Remote modem expects V.24 voice channel IP address; %s:%u for Rx traffic" , addrStr.c_str (), port);
745+ }
746+ }
747+
748+ /* Internal helper to setup the remote voice channel port. */
749+
750+ void V24UDPPort::createRemoteVCPort (std::string address, uint16_t port)
751+ {
752+ if (udp::Socket::lookup (address, port, m_remoteRTPAddr, m_remoteRTPAddrLen) != 0 )
753+ m_remoteRTPAddrLen = 0U ;
754+
755+ if (m_remoteRTPAddrLen > 0U ) {
756+ std::string addrStr = udp::Socket::address (m_remoteRTPAddr);
757+ LogWarning (LOG_HOST, " SECURITY: Remote modem expects V.24 voice channel IP address; %s:%u for Tx traffic" , addrStr.c_str (), port);
720758 }
721759}
722760
@@ -752,7 +790,7 @@ void V24UDPPort::writeHeartbeat()
752790 FSCHeartbeat hb = FSCHeartbeat ();
753791 hb.encode (buffer);
754792
755- m_ctrlFrameQueue->write (buffer, FSCHeartbeat::LENGTH, m_remoteAddr, m_remoteAddrLen );
793+ m_ctrlFrameQueue->write (buffer, FSCHeartbeat::LENGTH, m_remoteCtrlAddr, m_remoteCtrlAddrLen );
756794}
757795
758796/* Generate RTP message. */
0 commit comments