ip_port.cpp
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:4k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*
  2.  * The contents of this file are subject to the Mozilla Public
  3.  * License Version 1.1 (the "License"); you may not use this file
  4.  * except in compliance with the License. You may obtain a copy of
  5.  * the License at http://www.mozilla.org/MPL/
  6.  * 
  7.  * Software distributed under the License is distributed on an "AS
  8.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9.  * implied. See the License for the specific language governing
  10.  * rights and limitations under the License.
  11.  * 
  12.  * The Original Code is MPEG4IP.
  13.  * 
  14.  * The Initial Developer of the Original Code is Cisco Systems Inc.
  15.  * Portions created by Cisco Systems Inc. are
  16.  * Copyright (C) Cisco Systems Inc. 2000, 2001.  All Rights Reserved.
  17.  * 
  18.  * Contributor(s): 
  19.  *              Bill May        wmay@cisco.com
  20.  */
  21. /*
  22.  * ip_port.cpp - reserve IP port numbers for audio/video RTP streams
  23.  */
  24. #include "systems.h"
  25. #include "ip_port.h"
  26. #include "player_util.h"
  27. #include "our_config_file.h"
  28. /*
  29.  * CIpPort::CIpPort() - create ip socket, bind it to the local address
  30.  * (which assigns it a port number), and figure out what the port number
  31.  * is.
  32.  */
  33. CIpPort::CIpPort (in_port_t startport, in_port_t maxport)
  34. {
  35.   struct sockaddr_in saddr;
  36.   
  37.   m_next = NULL;
  38.   for (m_sock = -1; m_sock == -1 && startport <= maxport; startport++) {
  39.     // Start with min, go to max
  40.     m_sock = socket(AF_INET, SOCK_DGRAM, 0);
  41.     if (m_sock < 0) {
  42.       return;
  43.     }
  44.     saddr.sin_family = AF_INET;
  45.     saddr.sin_addr.s_addr = INADDR_ANY;
  46.     saddr.sin_port = htons(startport);
  47.     if (bind(m_sock, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) {
  48.       startport++;
  49.       closesocket(m_sock);
  50.       m_sock = -1;
  51.     }
  52.   } 
  53.       
  54. #if !defined(HAVE_SOCKLEN_T) || defined _WIN32
  55.   int socklen;
  56. #else
  57.   socklen_t socklen;
  58. #endif
  59.   socklen = sizeof(saddr);
  60.   if (getsockname(m_sock, (struct sockaddr *)&saddr, &socklen) < 0) {
  61.     closesocket(m_sock);
  62.     m_sock = -1;
  63.     return;
  64.   }
  65.   m_port_num = ntohs(saddr.sin_port);
  66. }
  67. /*
  68.  * CIpPort::~CIpPort() - close the socket we opened.
  69.  */
  70. CIpPort::~CIpPort (void)
  71. {
  72.   if (m_sock != -1) {
  73.     closesocket(m_sock);
  74.     m_sock = -1;
  75.   }
  76. }
  77. /*
  78.  * C2ConsecIpPort::C2ConsecIpPort() - get 2 consecutive, even-odd, ip
  79.  * port numbers
  80.  */
  81. C2ConsecIpPort::C2ConsecIpPort (CIpPort **global)
  82. {
  83.   CIpPort *newone;
  84.   m_first = m_second = NULL;
  85.   in_port_t firstport, maxport;
  86.   firstport = 1024;
  87.   maxport = ~0;
  88.   if (config.get_config_value(CONFIG_IPPORT_MIN) != -1) {
  89.     firstport = config.get_config_value(CONFIG_IPPORT_MIN);
  90.     if (config.get_config_value(CONFIG_IPPORT_MAX) != -1) {
  91.       maxport = config.get_config_value(CONFIG_IPPORT_MAX);
  92.       if (maxport <= firstport) {
  93. player_error_message("IP port configuration error - %u %u - using 65535 as max port value", 
  94.      firstport, maxport);
  95. maxport = ~0;
  96.       }
  97.     }
  98.   }
  99.   while (1) {
  100.     // first, get an even port number.  If not even, save it in the
  101.     // global queue.
  102.     do {
  103.       newone = new CIpPort(firstport, maxport);
  104.       if (newone->valid() == 0)
  105. return;
  106.       if ((newone->get_port_num() & 0x1) == 0x1) {
  107. newone->set_next(*global);
  108. *global = newone;
  109. firstport++;
  110.       }
  111.     } while ((newone->get_port_num() & 0x1) == 0x1);
  112.     player_debug_message("First port is %d", newone->get_port_num());
  113.     // Okay, save the first, get the 2nd.  If okay, just return
  114.     m_first = newone;
  115.     in_port_t next;
  116.     next = m_first->get_port_num() + 1;
  117.     m_second = new CIpPort(next, next);
  118.     if ((m_second->valid() == 1) &&
  119. (m_second->get_port_num() == next)) {
  120.       player_debug_message("Ip ports are %u %u", next - 1, next);
  121.       return;
  122.     } else {
  123.       player_debug_message("Got port %d invalid %d", m_second->get_port_num(),
  124.    m_second->valid());
  125.     }
  126.     // Not okay - save both off in the global queue, and try again...
  127.     m_first->set_next(*global);
  128.     *global = m_first;
  129.     m_first = NULL;
  130.     firstport = m_second->get_port_num() + 1;
  131.     m_second->set_next(*global);
  132.     *global = m_second;
  133.     m_second = NULL;
  134.   }
  135. }
  136. /*
  137.  * C2ConsecIpPort::~C2ConsecIpPort() - just delete the CIpPorts that
  138.  * we've saved.
  139.  */
  140. C2ConsecIpPort::~C2ConsecIpPort (void)
  141. {
  142.   if (m_second) {
  143.     delete m_second;
  144.     m_second = NULL;
  145.   }
  146.   if (m_first) {
  147.     delete m_first;
  148.     m_first = NULL;
  149.   }
  150. }