Changeset 696


Ignore:
Timestamp:
11/15/11 12:45:20 (6 months ago)
Author:
shiretu
Message:

-- added NAT traversal capabilities to RTSP

Files:
4 added
14 edited

Legend:

Unmodified
Added
Removed
  • branches/1.0/constants/constants.lua

    r658 r696  
    3535CONF_PROTOCOL_UDP_RTCP="inboundUdpRtcp", 
    3636CONF_PROTOCOL_INBOUND_RTSP="inboundRtsp", 
     37CONF_PROTOCOL_RTP_NAT_TRAVERSAL="rtpNatTraversal", 
    3738 
    3839-- HTTP protocols 
     
    614615        file:write("public static class "..arg[4].."\r\n{\r\n") 
    615616        for k,v in orderedPairs(constants) do 
     617                print (k,v) 
    616618                if(type(v)=="string") then 
    617619                        file:write("public const string "..k.."=\""..v.."\";\n") 
     
    621623        end 
    622624        file:write("}\r\n}\r\n") 
     625        file:close() 
    623626end 
    624627 
  • branches/1.0/sources/common/include/defines.h

    r658 r696  
    319319#define CONF_PROTOCOL_OUTBOUND_XML_VARIANT "outboundXmlVariant" 
    320320#define CONF_PROTOCOL_OUTBOUND_XML_VARIANT_LEN 18 
     321#define CONF_PROTOCOL_RTP_NAT_TRAVERSAL "rtpNatTraversal" 
     322#define CONF_PROTOCOL_RTP_NAT_TRAVERSAL_LEN 15 
    321323#define CONF_PROTOCOL_RTSP_RTCP "inboundRtspRtcp" 
    322324#define CONF_PROTOCOL_RTSP_RTCP_LEN 15 
  • branches/1.0/sources/thelib/include/protocols/protocoltypes.h

    r566 r696  
    6868#define PT_INBOUND_RTP                  MAKE_TAG4('I','R','T','P') 
    6969#define PT_OUTBOUND_RTP                 MAKE_TAG4('O','R','T','P') 
     70#define PT_RTP_NAT_TRAVERSAL    MAKE_TAG5('R','N','A','T','T') 
    7071 
    7172//MMS 
  • branches/1.0/sources/thelib/include/protocols/rtp/connectivity/outboundconnectivity.h

    r694 r696  
    2626class BaseOutNetRTPUDPStream; 
    2727class RTSPProtocol; 
     28class NATTraversalProtocol; 
    2829 
    2930struct RTPClient { 
     
    9192        uint64_t _startupTime; 
    9293        RTPClient _rtpClient; 
    93         bool _hasAudio; 
     94 
    9495        bool _hasVideo; 
    95  
    9696        int32_t _videoDataFd; 
    9797        uint16_t _videoDataPort; 
    9898        int32_t _videoRTCPFd; 
    9999        uint16_t _videoRTCPPort; 
     100        NATTraversalProtocol *_pVideoNATData; 
     101        NATTraversalProtocol *_pVideoNATRTCP; 
    100102 
     103        bool _hasAudio; 
    101104        int32_t _audioDataFd; 
    102105        uint16_t _audioDataPort; 
    103106        int32_t _audioRTCPFd; 
    104107        uint16_t _audioRTCPPort; 
     108        NATTraversalProtocol *_pAudioNATData; 
     109        NATTraversalProtocol *_pAudioNATRTCP; 
    105110public: 
    106111        OutboundConnectivity(bool forceTcp, RTSPProtocol *pRTSPProtocol); 
     
    129134private: 
    130135        bool InitializePorts(int32_t &dataFd, uint16_t &dataPort, 
    131                         int32_t &RTCPFd, uint16_t &RTCPPort); 
     136                        NATTraversalProtocol **ppNATData, int32_t &RTCPFd, uint16_t &RTCPPort, 
     137                        NATTraversalProtocol **ppNATRTCP); 
    132138        bool FeedData(msghdr &message, double absoluteTimestamp, bool isAudio); 
    133139}; 
  • branches/1.0/sources/thelib/src/protocols/defaultprotocolfactory.cpp

    r566 r696  
    4343#include "protocols/mms/mmsprotocol.h" 
    4444#include "protocols/rawhttpstream/inboundrawhttpstreamprotocol.h" 
     45#include "protocols/rtp/nattraversalprotocol.h" 
    4546 
    4647DefaultProtocolFactory::DefaultProtocolFactory() 
     
    9495        ADD_VECTOR_END(result, PT_RTCP); 
    9596        ADD_VECTOR_END(result, PT_INBOUND_RTP); 
     97        ADD_VECTOR_END(result, PT_RTP_NAT_TRAVERSAL); 
    9698#endif /* HAS_PROTOCOL_RTP */ 
    9799#ifdef HAS_PROTOCOL_CLI 
     
    151153        ADD_VECTOR_END(result, CONF_PROTOCOL_INBOUND_RTSP_RTP); 
    152154        ADD_VECTOR_END(result, CONF_PROTOCOL_INBOUND_UDP_RTP); 
     155        ADD_VECTOR_END(result, CONF_PROTOCOL_RTP_NAT_TRAVERSAL); 
    153156#endif /* HAS_PROTOCOL_RTP */ 
    154157#ifdef HAS_PROTOCOL_CLI 
     
    229232                ADD_VECTOR_END(result, PT_UDP); 
    230233                ADD_VECTOR_END(result, PT_INBOUND_RTP); 
     234        } else if (name == CONF_PROTOCOL_RTP_NAT_TRAVERSAL) { 
     235                ADD_VECTOR_END(result, PT_UDP); 
     236                ADD_VECTOR_END(result, PT_RTP_NAT_TRAVERSAL); 
    231237        } 
    232238#endif /* HAS_PROTOCOL_RTP */ 
     
    387393                case PT_INBOUND_RTP: 
    388394                        pResult = new InboundRTPProtocol(); 
     395                        break; 
     396                case PT_RTP_NAT_TRAVERSAL: 
     397                        pResult = new NATTraversalProtocol(); 
    389398                        break; 
    390399#endif /* HAS_PROTOCOL_RTP */ 
  • branches/1.0/sources/thelib/src/protocols/rtp/basertspappprotocolhandler.cpp

    r694 r696  
    732732        //6. prepare the response 
    733733        pFrom->PushResponseFirstLine(RTSP_VERSION_1_0, 200, "OK"); 
    734         pFrom->PushResponseHeader(RTSP_HEADERS_RANGE, "npt=0.0-"); 
    735  
    736         string rtpInfoVideo = ""; 
    737         string rtpInfoAudio = ""; 
    738         if (pFrom->GetCustomParameters().HasKey("videoTrackUri")) { 
    739                 rtpInfoVideo = format("url=%s;seq=%u;rtptime=%u", 
    740                                 STR(pFrom->GetCustomParameters()["videoTrackUri"]), 
    741                                 pOutboundConnectivity->GetLastVideoSequence(), 
    742                                 0); 
    743         } 
    744         if (pFrom->GetCustomParameters().HasKey("audioTrackId")) { 
    745                 rtpInfoAudio = format("url=%s;seq=%u;rtptime=%u", 
    746                                 STR(pFrom->GetCustomParameters()["audioTrackId"]), 
    747                                 pOutboundConnectivity->GetLastAudioSequence(), 
    748                                 0); 
    749         } 
    750         string rtpInfo = rtpInfoVideo; 
    751         if (rtpInfo != "") { 
    752                 if (rtpInfoAudio != "") { 
    753                         rtpInfo += ", " + rtpInfoAudio; 
    754                 } 
    755         } else { 
    756                 rtpInfo = rtpInfoAudio; 
    757         } 
    758734 
    759735        //7. Done 
     
    16701646        result += format("o=- %"PRIu32" 0 IN IP4 %s\r\n", pFrom->GetId(), STR(nearAddress)); 
    16711647        result += "s=" + targetStreamName + "\r\n"; 
    1672         result += "u=http://www.rtmpd.com/\r\n"; 
    1673         result += "e=crtmpserver@gmail.com\r\n"; 
    1674         result += "c=IN IP4 " + farAddress + "\r\n"; 
     1648        result += "u=http://www.evostream.com\r\n"; 
     1649        result += "e=contact@evostream.com\r\n"; 
     1650        result += "c=IN IP4 " + nearAddress + "\r\n"; 
    16751651        result += "t=0 0\r\n"; 
    16761652        result += "a=recvonly\r\n"; 
  • branches/1.0/sources/thelib/src/protocols/rtp/connectivity/outboundconnectivity.cpp

    r694 r696  
    2424#include "protocols/baseprotocol.h" 
    2525#include "protocols/rtp/rtspprotocol.h" 
     26#include "protocols/rtp/nattraversalprotocol.h" 
     27#include "netio/netio.h" 
     28#include "protocols/udpprotocol.h" 
    2629 
    2730OutboundConnectivity::OutboundConnectivity(bool forceTcp, RTSPProtocol *pRTSPProtocol) 
     
    5255        _pRTCPSOC = ((uint8_t *) _rtcpMessage.msg_iov[0].iov_base) + 24; 
    5356 
    54         _hasAudio = false; 
    5557        _hasVideo = false; 
    5658        _videoDataFd = -1; 
     
    5860        _videoRTCPFd = -1; 
    5961        _videoRTCPPort = 0; 
     62        _pVideoNATData = NULL; 
     63        _pVideoNATRTCP = NULL; 
     64 
     65        _hasAudio = false; 
    6066        _audioDataFd = -1; 
    6167        _audioDataPort = 0; 
    6268        _audioRTCPFd = -1; 
    6369        _audioRTCPPort = 0; 
     70        _pAudioNATData = NULL; 
     71        _pAudioNATRTCP = NULL; 
    6472 
    6573        _startupTime = (uint64_t) time(NULL); 
     
    7381                delete _pOutStream; 
    7482        } 
    75         CLOSE_SOCKET(_videoDataFd); 
    76         CLOSE_SOCKET(_videoRTCPFd); 
    77         CLOSE_SOCKET(_audioDataFd); 
    78         CLOSE_SOCKET(_audioRTCPFd); 
     83        if (_pVideoNATData != NULL) { 
     84                _pVideoNATData->EnqueueForDelete(); 
     85                _pVideoNATData = NULL; 
     86        } 
     87        if (_pVideoNATRTCP != NULL) { 
     88                _pVideoNATRTCP->EnqueueForDelete(); 
     89                _pVideoNATRTCP = NULL; 
     90        } 
     91        if (_pAudioNATData != NULL) { 
     92                _pAudioNATData->EnqueueForDelete(); 
     93                _pAudioNATData = NULL; 
     94        } 
     95        if (_pAudioNATRTCP != NULL) { 
     96                _pAudioNATRTCP->EnqueueForDelete(); 
     97                _pAudioNATRTCP = NULL; 
     98        } 
    7999} 
    80100 
     
    86106                _rtpClient.videoRtcpChannel = 3; 
    87107        } else { 
    88                 if (!InitializePorts(_videoDataFd, _videoDataPort, _videoRTCPFd, _videoRTCPPort)) { 
     108                if (!InitializePorts(_videoDataFd, _videoDataPort, &_pVideoNATData, 
     109                                _videoRTCPFd, _videoRTCPPort, &_pVideoNATRTCP)) { 
    89110                        FATAL("Unable to initialize video ports"); 
    90111                        return false; 
    91112                } 
    92                 if (!InitializePorts(_audioDataFd, _audioDataPort, _audioRTCPFd, _audioRTCPPort)) { 
     113                if (!InitializePorts(_audioDataFd, _audioDataPort, &_pAudioNATData, 
     114                                _audioRTCPFd, _audioRTCPPort, &_pAudioNATRTCP)) { 
    93115                        FATAL("Unable to initialize audio ports"); 
    94116                        return false; 
     
    161183        _rtpClient.videoRtcpAddress = rtcp; 
    162184        _rtpClient.protocolId = rtspProtocolId; 
    163         return true; 
     185        _pVideoNATData->SetOutboundAddress(&_rtpClient.videoDataAddress); 
     186        _pVideoNATRTCP->SetOutboundAddress(&_rtpClient.videoRtcpAddress); 
     187        return ((UDPCarrier *) _pVideoNATData->GetIOHandler())->StartAccept() 
     188                        &((UDPCarrier *) _pVideoNATRTCP->GetIOHandler())->StartAccept(); 
    164189} 
    165190 
     
    175200        _rtpClient.audioRtcpAddress = rtcp; 
    176201        _rtpClient.protocolId = rtspProtocolId; 
    177         return true; 
     202        _pAudioNATData->SetOutboundAddress(&_rtpClient.audioDataAddress); 
     203        _pAudioNATRTCP->SetOutboundAddress(&_rtpClient.audioRtcpAddress); 
     204        return ((UDPCarrier *) _pAudioNATData->GetIOHandler())->StartAccept() 
     205                        &((UDPCarrier *) _pAudioNATRTCP->GetIOHandler())->StartAccept(); 
    178206} 
    179207 
     
    233261 
    234262bool OutboundConnectivity::InitializePorts(int32_t &dataFd, uint16_t &dataPort, 
    235                 int32_t &RTCPFd, uint16_t &RTCPPort) { 
    236         for (int i = 0; i < 10; i++) { 
    237                 CLOSE_SOCKET(dataFd); 
    238                 CLOSE_SOCKET(RTCPFd); 
    239  
    240                 dataFd = socket(AF_INET, SOCK_DGRAM, 0); 
    241                 RTCPFd = socket(AF_INET, SOCK_DGRAM, 0); 
    242  
    243                 sockaddr_in address; 
    244                 memset(&address, 0, sizeof (address)); 
    245                 address.sin_family = AF_INET; 
    246                 address.sin_port = 0; 
    247                 address.sin_addr.s_addr = INADDR_ANY; 
    248                 if (bind(dataFd, (sockaddr *) & address, sizeof (address)) != 0) { 
    249                         int err = errno; 
    250                         WARN("Unable to bind. Error: %s (%d)", strerror(err), err); 
     263                NATTraversalProtocol **ppNATData, int32_t &RTCPFd, uint16_t &RTCPPort, 
     264                NATTraversalProtocol **ppNATRTCP) { 
     265        UDPCarrier *pCarrier1 = NULL; 
     266        UDPCarrier *pCarrier2 = NULL; 
     267        for (uint32_t i = 0; i < 10; i++) { 
     268                if (pCarrier1 != NULL) { 
     269                        delete pCarrier1; 
     270                        pCarrier1 = NULL; 
     271                } 
     272                if (pCarrier2 != NULL) { 
     273                        delete pCarrier2; 
     274                        pCarrier2 = NULL; 
     275                } 
     276 
     277                pCarrier1 = UDPCarrier::Create("0.0.0.0", 0); 
     278                if (pCarrier1 == NULL) { 
     279                        WARN("Unable to create UDP carrier for RTP"); 
    251280                        continue; 
    252281                } 
    253                 socklen_t len = sizeof (sockaddr); 
    254                 if (getsockname(dataFd, (sockaddr *) & address, &len) != 0) { 
    255                         ASSERT("Unable to get peer's address"); 
    256                 } 
    257                 dataPort = ENTOHS(address.sin_port); 
    258  
    259                 if ((dataPort % 2) != 0) { 
    260                         address.sin_port = EHTONS(dataPort - 1); 
     282 
     283                if ((pCarrier1->GetNearEndpointPort() % 2) == 0) { 
     284                        pCarrier2 = UDPCarrier::Create("0.0.0.0", 
     285                                        pCarrier1->GetNearEndpointPort() + 1); 
    261286                } else { 
    262                         address.sin_port = EHTONS(dataPort + 1); 
    263                 } 
    264                 if (bind(RTCPFd, (sockaddr *) & address, sizeof (address)) != 0) { 
    265                         int err = errno; 
    266                         WARN("Unable to bind on port %"PRIu16". Error: %s (%d)", 
    267                                         ENTOHS(address.sin_port), strerror(err), err); 
     287                        pCarrier2 = UDPCarrier::Create("0.0.0.0", 
     288                                        pCarrier1->GetNearEndpointPort() - 1); 
     289                } 
     290 
     291                if (pCarrier2 == NULL) { 
     292                        WARN("Unable to create UDP carrier for RTP"); 
    268293                        continue; 
    269294                } 
    270                 RTCPPort = ENTOHS(address.sin_port); 
    271  
    272                 if ((dataPort % 2) != 0) { 
    273                         uint16_t temp16 = dataPort; 
    274                         dataPort = RTCPPort; 
    275                         RTCPPort = temp16; 
    276  
    277                         int32_t temp32 = dataFd; 
    278                         dataFd = RTCPFd; 
    279                         RTCPFd = temp32; 
    280                         WARN("Ports switch"); 
    281                 } 
    282  
     295 
     296                if (pCarrier1->GetNearEndpointPort() > pCarrier2->GetNearEndpointPort()) { 
     297                        WARN("Switch carriers"); 
     298                        UDPCarrier *pTemp = pCarrier1; 
     299                        pCarrier1 = pCarrier2; 
     300                        pCarrier2 = pTemp; 
     301                } 
     302 
     303                Variant dummy; 
     304                //data 
     305 
     306 
     307                dataFd = pCarrier1->GetInboundFd(); 
     308                dataPort = pCarrier1->GetNearEndpointPort(); 
     309                *ppNATData = (NATTraversalProtocol *) ProtocolFactoryManager::CreateProtocolChain( 
     310                                CONF_PROTOCOL_RTP_NAT_TRAVERSAL, dummy); 
     311                if (*ppNATData == NULL) { 
     312                        FATAL("Unable to create the protocol chain %s", CONF_PROTOCOL_RTP_NAT_TRAVERSAL); 
     313                        return false; 
     314                } 
     315                pCarrier1->SetProtocol(((*ppNATData)->GetFarEndpoint())); 
     316                (*ppNATData)->GetFarEndpoint()->SetIOHandler(pCarrier1); 
     317 
     318                //RTCP 
     319                RTCPFd = pCarrier2->GetInboundFd(); 
     320                RTCPPort = pCarrier2->GetNearEndpointPort(); 
     321                *ppNATRTCP = (NATTraversalProtocol *) ProtocolFactoryManager::CreateProtocolChain( 
     322                                CONF_PROTOCOL_RTP_NAT_TRAVERSAL, dummy); 
     323                if (*ppNATRTCP == NULL) { 
     324                        FATAL("Unable to create the protocol chain %s", CONF_PROTOCOL_RTP_NAT_TRAVERSAL); 
     325                        (*ppNATData)->EnqueueForDelete(); 
     326                        return false; 
     327                } 
     328                pCarrier2->SetProtocol((*ppNATRTCP)->GetFarEndpoint()); 
     329                (*ppNATRTCP)->GetFarEndpoint()->SetIOHandler(pCarrier2); 
     330 
     331                //return pCarrier1->StartAccept() & pCarrier2->StartAccept(); 
    283332                return true; 
    284333        } 
    285334 
    286         FATAL("Unable to bind after 10 attempts"); 
     335        if (*ppNATData != NULL) { 
     336                (*ppNATData)->EnqueueForDelete(); 
     337                (*ppNATData) = NULL; 
     338        } 
     339        if (*ppNATRTCP != NULL) { 
     340                (*ppNATRTCP)->EnqueueForDelete(); 
     341                (*ppNATRTCP) = NULL; 
     342        } 
     343 
    287344        return false; 
    288345} 
  • trunk/constants/constants.lua

    r658 r696  
    3535CONF_PROTOCOL_UDP_RTCP="inboundUdpRtcp", 
    3636CONF_PROTOCOL_INBOUND_RTSP="inboundRtsp", 
     37CONF_PROTOCOL_RTP_NAT_TRAVERSAL="rtpNatTraversal", 
    3738 
    3839-- HTTP protocols 
     
    614615        file:write("public static class "..arg[4].."\r\n{\r\n") 
    615616        for k,v in orderedPairs(constants) do 
     617                print (k,v) 
    616618                if(type(v)=="string") then 
    617619                        file:write("public const string "..k.."=\""..v.."\";\n") 
     
    621623        end 
    622624        file:write("}\r\n}\r\n") 
     625        file:close() 
    623626end 
    624627 
  • trunk/sources/common/include/defines.h

    r658 r696  
    319319#define CONF_PROTOCOL_OUTBOUND_XML_VARIANT "outboundXmlVariant" 
    320320#define CONF_PROTOCOL_OUTBOUND_XML_VARIANT_LEN 18 
     321#define CONF_PROTOCOL_RTP_NAT_TRAVERSAL "rtpNatTraversal" 
     322#define CONF_PROTOCOL_RTP_NAT_TRAVERSAL_LEN 15 
    321323#define CONF_PROTOCOL_RTSP_RTCP "inboundRtspRtcp" 
    322324#define CONF_PROTOCOL_RTSP_RTCP_LEN 15 
  • trunk/sources/thelib/include/protocols/protocoltypes.h

    r566 r696  
    6868#define PT_INBOUND_RTP                  MAKE_TAG4('I','R','T','P') 
    6969#define PT_OUTBOUND_RTP                 MAKE_TAG4('O','R','T','P') 
     70#define PT_RTP_NAT_TRAVERSAL    MAKE_TAG5('R','N','A','T','T') 
    7071 
    7172//MMS 
  • trunk/sources/thelib/include/protocols/rtp/connectivity/outboundconnectivity.h

    r694 r696  
    2626class BaseOutNetRTPUDPStream; 
    2727class RTSPProtocol; 
     28class NATTraversalProtocol; 
    2829 
    2930struct RTPClient { 
     
    9192        uint64_t _startupTime; 
    9293        RTPClient _rtpClient; 
    93         bool _hasAudio; 
     94 
    9495        bool _hasVideo; 
    95  
    9696        int32_t _videoDataFd; 
    9797        uint16_t _videoDataPort; 
    9898        int32_t _videoRTCPFd; 
    9999        uint16_t _videoRTCPPort; 
     100        NATTraversalProtocol *_pVideoNATData; 
     101        NATTraversalProtocol *_pVideoNATRTCP; 
    100102 
     103        bool _hasAudio; 
    101104        int32_t _audioDataFd; 
    102105        uint16_t _audioDataPort; 
    103106        int32_t _audioRTCPFd; 
    104107        uint16_t _audioRTCPPort; 
     108        NATTraversalProtocol *_pAudioNATData; 
     109        NATTraversalProtocol *_pAudioNATRTCP; 
    105110public: 
    106111        OutboundConnectivity(bool forceTcp, RTSPProtocol *pRTSPProtocol); 
     
    129134private: 
    130135        bool InitializePorts(int32_t &dataFd, uint16_t &dataPort, 
    131                         int32_t &RTCPFd, uint16_t &RTCPPort); 
     136                        NATTraversalProtocol **ppNATData, int32_t &RTCPFd, uint16_t &RTCPPort, 
     137                        NATTraversalProtocol **ppNATRTCP); 
    132138        bool FeedData(msghdr &message, double absoluteTimestamp, bool isAudio); 
    133139}; 
  • trunk/sources/thelib/src/protocols/defaultprotocolfactory.cpp

    r566 r696  
    4343#include "protocols/mms/mmsprotocol.h" 
    4444#include "protocols/rawhttpstream/inboundrawhttpstreamprotocol.h" 
     45#include "protocols/rtp/nattraversalprotocol.h" 
    4546 
    4647DefaultProtocolFactory::DefaultProtocolFactory() 
     
    9495        ADD_VECTOR_END(result, PT_RTCP); 
    9596        ADD_VECTOR_END(result, PT_INBOUND_RTP); 
     97        ADD_VECTOR_END(result, PT_RTP_NAT_TRAVERSAL); 
    9698#endif /* HAS_PROTOCOL_RTP */ 
    9799#ifdef HAS_PROTOCOL_CLI 
     
    151153        ADD_VECTOR_END(result, CONF_PROTOCOL_INBOUND_RTSP_RTP); 
    152154        ADD_VECTOR_END(result, CONF_PROTOCOL_INBOUND_UDP_RTP); 
     155        ADD_VECTOR_END(result, CONF_PROTOCOL_RTP_NAT_TRAVERSAL); 
    153156#endif /* HAS_PROTOCOL_RTP */ 
    154157#ifdef HAS_PROTOCOL_CLI 
     
    229232                ADD_VECTOR_END(result, PT_UDP); 
    230233                ADD_VECTOR_END(result, PT_INBOUND_RTP); 
     234        } else if (name == CONF_PROTOCOL_RTP_NAT_TRAVERSAL) { 
     235                ADD_VECTOR_END(result, PT_UDP); 
     236                ADD_VECTOR_END(result, PT_RTP_NAT_TRAVERSAL); 
    231237        } 
    232238#endif /* HAS_PROTOCOL_RTP */ 
     
    387393                case PT_INBOUND_RTP: 
    388394                        pResult = new InboundRTPProtocol(); 
     395                        break; 
     396                case PT_RTP_NAT_TRAVERSAL: 
     397                        pResult = new NATTraversalProtocol(); 
    389398                        break; 
    390399#endif /* HAS_PROTOCOL_RTP */ 
  • trunk/sources/thelib/src/protocols/rtp/basertspappprotocolhandler.cpp

    r694 r696  
    732732        //6. prepare the response 
    733733        pFrom->PushResponseFirstLine(RTSP_VERSION_1_0, 200, "OK"); 
    734         pFrom->PushResponseHeader(RTSP_HEADERS_RANGE, "npt=0.0-"); 
    735  
    736         string rtpInfoVideo = ""; 
    737         string rtpInfoAudio = ""; 
    738         if (pFrom->GetCustomParameters().HasKey("videoTrackUri")) { 
    739                 rtpInfoVideo = format("url=%s;seq=%u;rtptime=%u", 
    740                                 STR(pFrom->GetCustomParameters()["videoTrackUri"]), 
    741                                 pOutboundConnectivity->GetLastVideoSequence(), 
    742                                 0); 
    743         } 
    744         if (pFrom->GetCustomParameters().HasKey("audioTrackId")) { 
    745                 rtpInfoAudio = format("url=%s;seq=%u;rtptime=%u", 
    746                                 STR(pFrom->GetCustomParameters()["audioTrackId"]), 
    747                                 pOutboundConnectivity->GetLastAudioSequence(), 
    748                                 0); 
    749         } 
    750         string rtpInfo = rtpInfoVideo; 
    751         if (rtpInfo != "") { 
    752                 if (rtpInfoAudio != "") { 
    753                         rtpInfo += ", " + rtpInfoAudio; 
    754                 } 
    755         } else { 
    756                 rtpInfo = rtpInfoAudio; 
    757         } 
    758734 
    759735        //7. Done 
     
    16701646        result += format("o=- %"PRIu32" 0 IN IP4 %s\r\n", pFrom->GetId(), STR(nearAddress)); 
    16711647        result += "s=" + targetStreamName + "\r\n"; 
    1672         result += "u=http://www.rtmpd.com/\r\n"; 
    1673         result += "e=crtmpserver@gmail.com\r\n"; 
    1674         result += "c=IN IP4 " + farAddress + "\r\n"; 
     1648        result += "u=http://www.evostream.com\r\n"; 
     1649        result += "e=contact@evostream.com\r\n"; 
     1650        result += "c=IN IP4 " + nearAddress + "\r\n"; 
    16751651        result += "t=0 0\r\n"; 
    16761652        result += "a=recvonly\r\n"; 
  • trunk/sources/thelib/src/protocols/rtp/connectivity/outboundconnectivity.cpp

    r694 r696  
    2424#include "protocols/baseprotocol.h" 
    2525#include "protocols/rtp/rtspprotocol.h" 
     26#include "protocols/rtp/nattraversalprotocol.h" 
     27#include "netio/netio.h" 
     28#include "protocols/udpprotocol.h" 
    2629 
    2730OutboundConnectivity::OutboundConnectivity(bool forceTcp, RTSPProtocol *pRTSPProtocol) 
     
    5255        _pRTCPSOC = ((uint8_t *) _rtcpMessage.msg_iov[0].iov_base) + 24; 
    5356 
    54         _hasAudio = false; 
    5557        _hasVideo = false; 
    5658        _videoDataFd = -1; 
     
    5860        _videoRTCPFd = -1; 
    5961        _videoRTCPPort = 0; 
     62        _pVideoNATData = NULL; 
     63        _pVideoNATRTCP = NULL; 
     64 
     65        _hasAudio = false; 
    6066        _audioDataFd = -1; 
    6167        _audioDataPort = 0; 
    6268        _audioRTCPFd = -1; 
    6369        _audioRTCPPort = 0; 
     70        _pAudioNATData = NULL; 
     71        _pAudioNATRTCP = NULL; 
    6472 
    6573        _startupTime = (uint64_t) time(NULL); 
     
    7381                delete _pOutStream; 
    7482        } 
    75         CLOSE_SOCKET(_videoDataFd); 
    76         CLOSE_SOCKET(_videoRTCPFd); 
    77         CLOSE_SOCKET(_audioDataFd); 
    78         CLOSE_SOCKET(_audioRTCPFd); 
     83        if (_pVideoNATData != NULL) { 
     84                _pVideoNATData->EnqueueForDelete(); 
     85                _pVideoNATData = NULL; 
     86        } 
     87        if (_pVideoNATRTCP != NULL) { 
     88                _pVideoNATRTCP->EnqueueForDelete(); 
     89                _pVideoNATRTCP = NULL; 
     90        } 
     91        if (_pAudioNATData != NULL) { 
     92                _pAudioNATData->EnqueueForDelete(); 
     93                _pAudioNATData = NULL; 
     94        } 
     95        if (_pAudioNATRTCP != NULL) { 
     96                _pAudioNATRTCP->EnqueueForDelete(); 
     97                _pAudioNATRTCP = NULL; 
     98        } 
    7999} 
    80100 
     
    86106                _rtpClient.videoRtcpChannel = 3; 
    87107        } else { 
    88                 if (!InitializePorts(_videoDataFd, _videoDataPort, _videoRTCPFd, _videoRTCPPort)) { 
     108                if (!InitializePorts(_videoDataFd, _videoDataPort, &_pVideoNATData, 
     109                                _videoRTCPFd, _videoRTCPPort, &_pVideoNATRTCP)) { 
    89110                        FATAL("Unable to initialize video ports"); 
    90111                        return false; 
    91112                } 
    92                 if (!InitializePorts(_audioDataFd, _audioDataPort, _audioRTCPFd, _audioRTCPPort)) { 
     113                if (!InitializePorts(_audioDataFd, _audioDataPort, &_pAudioNATData, 
     114                                _audioRTCPFd, _audioRTCPPort, &_pAudioNATRTCP)) { 
    93115                        FATAL("Unable to initialize audio ports"); 
    94116                        return false; 
     
    161183        _rtpClient.videoRtcpAddress = rtcp; 
    162184        _rtpClient.protocolId = rtspProtocolId; 
    163         return true; 
     185        _pVideoNATData->SetOutboundAddress(&_rtpClient.videoDataAddress); 
     186        _pVideoNATRTCP->SetOutboundAddress(&_rtpClient.videoRtcpAddress); 
     187        return ((UDPCarrier *) _pVideoNATData->GetIOHandler())->StartAccept() 
     188                        &((UDPCarrier *) _pVideoNATRTCP->GetIOHandler())->StartAccept(); 
    164189} 
    165190 
     
    175200        _rtpClient.audioRtcpAddress = rtcp; 
    176201        _rtpClient.protocolId = rtspProtocolId; 
    177         return true; 
     202        _pAudioNATData->SetOutboundAddress(&_rtpClient.audioDataAddress); 
     203        _pAudioNATRTCP->SetOutboundAddress(&_rtpClient.audioRtcpAddress); 
     204        return ((UDPCarrier *) _pAudioNATData->GetIOHandler())->StartAccept() 
     205                        &((UDPCarrier *) _pAudioNATRTCP->GetIOHandler())->StartAccept(); 
    178206} 
    179207 
     
    233261 
    234262bool OutboundConnectivity::InitializePorts(int32_t &dataFd, uint16_t &dataPort, 
    235                 int32_t &RTCPFd, uint16_t &RTCPPort) { 
    236         for (int i = 0; i < 10; i++) { 
    237                 CLOSE_SOCKET(dataFd); 
    238                 CLOSE_SOCKET(RTCPFd); 
    239  
    240                 dataFd = socket(AF_INET, SOCK_DGRAM, 0); 
    241                 RTCPFd = socket(AF_INET, SOCK_DGRAM, 0); 
    242  
    243                 sockaddr_in address; 
    244                 memset(&address, 0, sizeof (address)); 
    245                 address.sin_family = AF_INET; 
    246                 address.sin_port = 0; 
    247                 address.sin_addr.s_addr = INADDR_ANY; 
    248                 if (bind(dataFd, (sockaddr *) & address, sizeof (address)) != 0) { 
    249                         int err = errno; 
    250                         WARN("Unable to bind. Error: %s (%d)", strerror(err), err); 
     263                NATTraversalProtocol **ppNATData, int32_t &RTCPFd, uint16_t &RTCPPort, 
     264                NATTraversalProtocol **ppNATRTCP) { 
     265        UDPCarrier *pCarrier1 = NULL; 
     266        UDPCarrier *pCarrier2 = NULL; 
     267        for (uint32_t i = 0; i < 10; i++) { 
     268                if (pCarrier1 != NULL) { 
     269                        delete pCarrier1; 
     270                        pCarrier1 = NULL; 
     271                } 
     272                if (pCarrier2 != NULL) { 
     273                        delete pCarrier2; 
     274                        pCarrier2 = NULL; 
     275                } 
     276 
     277                pCarrier1 = UDPCarrier::Create("0.0.0.0", 0); 
     278                if (pCarrier1 == NULL) { 
     279                        WARN("Unable to create UDP carrier for RTP"); 
    251280                        continue; 
    252281                } 
    253                 socklen_t len = sizeof (sockaddr); 
    254                 if (getsockname(dataFd, (sockaddr *) & address, &len) != 0) { 
    255                         ASSERT("Unable to get peer's address"); 
    256                 } 
    257                 dataPort = ENTOHS(address.sin_port); 
    258  
    259                 if ((dataPort % 2) != 0) { 
    260                         address.sin_port = EHTONS(dataPort - 1); 
     282 
     283                if ((pCarrier1->GetNearEndpointPort() % 2) == 0) { 
     284                        pCarrier2 = UDPCarrier::Create("0.0.0.0", 
     285                                        pCarrier1->GetNearEndpointPort() + 1); 
    261286                } else { 
    262                         address.sin_port = EHTONS(dataPort + 1); 
    263                 } 
    264                 if (bind(RTCPFd, (sockaddr *) & address, sizeof (address)) != 0) { 
    265                         int err = errno; 
    266                         WARN("Unable to bind on port %"PRIu16". Error: %s (%d)", 
    267                                         ENTOHS(address.sin_port), strerror(err), err); 
     287                        pCarrier2 = UDPCarrier::Create("0.0.0.0", 
     288                                        pCarrier1->GetNearEndpointPort() - 1); 
     289                } 
     290 
     291                if (pCarrier2 == NULL) { 
     292                        WARN("Unable to create UDP carrier for RTP"); 
    268293                        continue; 
    269294                } 
    270                 RTCPPort = ENTOHS(address.sin_port); 
    271  
    272                 if ((dataPort % 2) != 0) { 
    273                         uint16_t temp16 = dataPort; 
    274                         dataPort = RTCPPort; 
    275                         RTCPPort = temp16; 
    276  
    277                         int32_t temp32 = dataFd; 
    278                         dataFd = RTCPFd; 
    279                         RTCPFd = temp32; 
    280                         WARN("Ports switch"); 
    281                 } 
    282  
     295 
     296                if (pCarrier1->GetNearEndpointPort() > pCarrier2->GetNearEndpointPort()) { 
     297                        WARN("Switch carriers"); 
     298                        UDPCarrier *pTemp = pCarrier1; 
     299                        pCarrier1 = pCarrier2; 
     300                        pCarrier2 = pTemp; 
     301                } 
     302 
     303                Variant dummy; 
     304                //data 
     305 
     306 
     307                dataFd = pCarrier1->GetInboundFd(); 
     308                dataPort = pCarrier1->GetNearEndpointPort(); 
     309                *ppNATData = (NATTraversalProtocol *) ProtocolFactoryManager::CreateProtocolChain( 
     310                                CONF_PROTOCOL_RTP_NAT_TRAVERSAL, dummy); 
     311                if (*ppNATData == NULL) { 
     312                        FATAL("Unable to create the protocol chain %s", CONF_PROTOCOL_RTP_NAT_TRAVERSAL); 
     313                        return false; 
     314                } 
     315                pCarrier1->SetProtocol(((*ppNATData)->GetFarEndpoint())); 
     316                (*ppNATData)->GetFarEndpoint()->SetIOHandler(pCarrier1); 
     317 
     318                //RTCP 
     319                RTCPFd = pCarrier2->GetInboundFd(); 
     320                RTCPPort = pCarrier2->GetNearEndpointPort(); 
     321                *ppNATRTCP = (NATTraversalProtocol *) ProtocolFactoryManager::CreateProtocolChain( 
     322                                CONF_PROTOCOL_RTP_NAT_TRAVERSAL, dummy); 
     323                if (*ppNATRTCP == NULL) { 
     324                        FATAL("Unable to create the protocol chain %s", CONF_PROTOCOL_RTP_NAT_TRAVERSAL); 
     325                        (*ppNATData)->EnqueueForDelete(); 
     326                        return false; 
     327                } 
     328                pCarrier2->SetProtocol((*ppNATRTCP)->GetFarEndpoint()); 
     329                (*ppNATRTCP)->GetFarEndpoint()->SetIOHandler(pCarrier2); 
     330 
     331                //return pCarrier1->StartAccept() & pCarrier2->StartAccept(); 
    283332                return true; 
    284333        } 
    285334 
    286         FATAL("Unable to bind after 10 attempts"); 
     335        if (*ppNATData != NULL) { 
     336                (*ppNATData)->EnqueueForDelete(); 
     337                (*ppNATData) = NULL; 
     338        } 
     339        if (*ppNATRTCP != NULL) { 
     340                (*ppNATRTCP)->EnqueueForDelete(); 
     341                (*ppNATRTCP) = NULL; 
     342        } 
     343 
    287344        return false; 
    288345} 
Note: See TracChangeset for help on using the changeset viewer.