示例#1
0
int
ACE_Name_Request::decode (void)
{
  ACE_TRACE ("ACE_Name_Request::decode");
  // Decode the fixed-sized portion first.
  this->transfer_.block_forever_ = ACE_NTOHL (this->transfer_.block_forever_);
  this->transfer_.usec_timeout_  = ACE_NTOHL (this->transfer_.usec_timeout_);
#if defined (ACE_LITTLE_ENDIAN)
  ACE_UINT64 secs = this->transfer_.sec_timeout_;
  ACE_CDR::swap_8 ((const char *)&secs, (char *)&this->transfer_.sec_timeout_);
#endif
  this->transfer_.length_ = ACE_NTOHL (this->transfer_.length_);
  this->transfer_.msg_type_ = ACE_NTOHL (this->transfer_.msg_type_);
  this->transfer_.name_len_ = ACE_NTOHL (this->transfer_.name_len_);
  this->transfer_.value_len_ = ACE_NTOHL (this->transfer_.value_len_);
  this->transfer_.type_len_ = ACE_NTOHL (this->transfer_.type_len_);

  size_t nv_data_len =
    (this->transfer_.name_len_ + this->transfer_.value_len_)
    / sizeof (ACE_WCHAR_T);

  for (size_t i = 0; i < nv_data_len; i++)
    this->transfer_.data_[i] =
      ACE_NTOHS (this->transfer_.data_[i]);

  this->name_ = this->transfer_.data_;
  this->value_ = &this->name_[this->transfer_.name_len_ / sizeof (ACE_WCHAR_T)];
  this->type_ = (char *)(&this->value_[this->transfer_.value_len_ / sizeof (ACE_WCHAR_T)]);
  this->type_[this->transfer_.type_len_] = '\0';

  // Decode the variable-sized portion.
  return 0;
}
示例#2
0
unsigned short CRtpPacket::GetSeqNum()const
{
    if (NULL == m_pFixedHead)
    {
        //BP_RUN_LOG_ERR(UNDEF_ERRCODE, "CRtpPacket::GetSeqNum","Rtp packet get seqnum fail packet is null.");
        return 0;
    }

    return ACE_NTOHS(m_pFixedHead->seq_no);
}
unsigned short
Message::calcChecksum() const
{
    unsigned short cs = 0;
    unsigned short n = (length() - 2) / 2;
    unsigned short * d = (unsigned short *) data();

    for (int i = 0; i < n; ++i)
        cs += ACE_NTOHS(d[i]);
    if ((length() & 1) == 1)
        cs ^= (unsigned short) data()[length()-3];

    return cs;
}
int
ACE_INET_Addr::set (u_short port_number,
                    const char host_name[],
                    int encode,
                    int address_family)
{
  ACE_TRACE ("ACE_INET_Addr::set");

  // Yow, someone gave us a NULL host_name!
  if (host_name == 0)
    {
      errno = EINVAL;
      return -1;
    }

  this->reset_i ();
  ACE_OS::memset ((void *) &this->inet_addr_,
                  0,
                  sizeof this->inet_addr_);

#if defined (ACE_HAS_IPV6)
  // Let the IPv4 case fall through to the non-IPv6-capable section.
  // We don't need the additional getaddrinfo() capability and the Linux
  // getaddrinfo() is substantially slower than gethostbyname() w/
  // large vlans.
#  if defined (ACE_USES_IPV4_IPV6_MIGRATION)
  if (address_family == AF_UNSPEC && !ACE::ipv6_enabled ())
    address_family = AF_INET;
#  endif /* ACE_USES_IPV4_IPV6_MIGRATION */
  if (address_family != AF_INET)
    {
#  if defined (ACE_HAS_GETHOSTBYNAME2)
      hostent hentry;
      hostent *hp;
      ACE_HOSTENT_DATA buf;
      int h_error = 0;  // Not the same as errno!

      if (0 == ::gethostbyname2_r (host_name, AF_INET6, &hentry,
                                   buf, sizeof(buf), &hp, &h_error))
        {
          if (hp != 0)
            {
              this->set_type (hp->h_addrtype);
              for (size_t i = 0; hp->h_addr_list[i]; ++i)
                {
                  union ip46 next_addr;
                  struct sockaddr_in6 *next_addr_in6 = &next_addr.in6_;
                  (void) ACE_OS::memset (&next_addr, 0, sizeof (next_addr));
                  next_addr_in6->sin6_family = AF_INET6;
                  next_addr_in6->sin6_port =
                    encode ? ACE_NTOHS (port_number) : port_number;
#ifdef ACE_HAS_SOCKADDR_IN6_SIN6_LEN
                  next_addr_in6_->sin6_len = hp->h_length;
#endif
                  (void) ACE_OS::memcpy ((void *) &next_addr_in6->sin6_addr,
                                         hp->h_addr_list[i],
                                         hp->h_length);
                  this->inet_addrs_.push_back (next_addr);
                }
              this->reset ();

              return 0;
            }
        }
        errno = h_error;
        if (address_family == AF_INET6)
          return -1;
#  else
      struct addrinfo hints;
      struct addrinfo *res = 0, *curr = 0;
      int error = 0;
      ACE_OS::memset (&hints, 0, sizeof (hints));
      hints.ai_family = AF_INET6;
      // Note - specify the socktype here to avoid getting multiple entries
      // returned with the same address for different socket types or
      // protocols. If this causes a problem for some reason (an address that's
      // available for TCP but not UDP, or vice-versa) this will need to change
      // back to unrestricted hints and weed out the duplicate addresses by
      // searching this->inet_addrs_ which would slow things down.
      hints.ai_socktype = SOCK_STREAM;
      if ((error = ::getaddrinfo (host_name, 0, &hints, &res)) == 0)
        {
          this->set_type (res->ai_family);
          for (curr = res; curr; curr = curr->ai_next)
            {
              union ip46 next_addr;
              if (curr->ai_family == AF_INET6)
                {
                  ACE_OS::memcpy (&next_addr.in6_,
                                  curr->ai_addr,
                                  curr->ai_addrlen);
                  next_addr.in6_.sin6_port =
                    encode ? ACE_NTOHS (port_number) : port_number;
                }
              else
                {
                  ACE_OS::memcpy (&next_addr.in4_,
                                  curr->ai_addr,
                                  curr->ai_addrlen);
                  next_addr.in4_.sin_port =
                    encode ? ACE_NTOHS (port_number) : port_number;
                }
              this->inet_addrs_.push_back (next_addr);
            }
          this->reset ();
          ::freeaddrinfo (res);
          return 0;
        }
      if (address_family == AF_INET6)
        {
          if (res)
            ::freeaddrinfo(res);
          errno = error;
          return -1;
        }
#  endif /* ACE_HAS_GETHOSTBYNAME2 */
      // Let AF_UNSPEC try again w/ IPv4.
    }
#endif /* ACE_HAS_IPV6 */

  // IPv6 not supported... insure the family is set to IPv4
  address_family = AF_INET;
  this->set_type (address_family);
  this->inet_addr_.in4_.sin_family = static_cast<short> (address_family);
#ifdef ACE_HAS_SOCKADDR_IN_SIN_LEN
  this->inet_addr_.in4_.sin_len = sizeof (this->inet_addr_.in4_);
#endif
  struct in_addr addrv4;
  if (ACE_OS::inet_aton (host_name,
                         &addrv4) == 1)
    {
      this->inet_addrs_iter_ = this->inet_addrs_.end ();
      return this->set (port_number,
                        encode ? ACE_NTOHL (addrv4.s_addr) : addrv4.s_addr,
                        encode);
    }

  hostent hentry;
  ACE_HOSTENT_DATA buf;
  int h_error = 0;  // Not the same as errno!

  hostent *hp = ACE_OS::gethostbyname_r (host_name, &hentry,
                                         buf, &h_error);
  if (hp == 0)
    {
      errno = h_error;
      return -1;
    }

  this->set_type (hp->h_addrtype);
  for (size_t i = 0; hp->h_addr_list[i]; ++i)
    {
      union ip46 next_addr;
      struct sockaddr_in *next_addr_in = (struct sockaddr_in *)&next_addr.in4_;
      (void) ACE_OS::memset (&next_addr, 0, sizeof (next_addr));
      next_addr_in->sin_family = AF_INET;
      next_addr_in->sin_port = encode ? ACE_NTOHS (port_number) : port_number;
      (void) ACE_OS::memcpy ((void *) &next_addr_in->sin_addr,
                             hp->h_addr_list[i],
                             hp->h_length);
      this->inet_addrs_.push_back (next_addr);
    }
  this->reset ();
  return 0;
}
int
InfoRepoMulticastResponder::handle_input(ACE_HANDLE)
{
  if (OpenDDS::DCPS::DCPS_debug_level > 0)
    ACE_DEBUG((LM_DEBUG, "Entered InfoRepoMulticastResponder::handle_input\n"));

  // The length of the service name string that follows.
  CORBA::Short header;
  // Port to which to reply.
  ACE_UINT16 remote_port;
  // Name of the service for which the client is looking.
  char object_key[BUFSIZ];

  ACE_INET_Addr remote_addr;

  // Take a peek at the header to find out how long is the service
  // name string we should receive.
  ssize_t n = this->mcast_dgram_.recv(&header,
                                      sizeof(header),
                                      remote_addr,
                                      MSG_PEEK);

  if (n <= 0)
    ACE_ERROR_RETURN((LM_ERROR,
                      "InfoRepoMulticastResponder::handle_input - peek %d\n",
                      n),
                     0);

  else if (ACE_NTOHS(header) <= 0)
    ACE_ERROR_RETURN((LM_ERROR,
                      "InfoRepoMulticastResponder::handle_input() Header value < 1\n"),
                     0);

  // Receive full client multicast request.
  const int iovcnt = 3;
  iovec iov[iovcnt];

  iov[0].iov_base = (char *) &header;
  iov[0].iov_len  = sizeof(header);
  iov[1].iov_base = (char *) &remote_port;
  iov[1].iov_len  = sizeof(ACE_UINT16);
  iov[2].iov_base = (char *) object_key;
  iov[2].iov_len  = ACE_NTOHS(header);

  // Read the iovec.
  n = this->mcast_dgram_.recv(iov,
                              iovcnt,
                              remote_addr);

  if (n <= 0)
    ACE_ERROR_RETURN((LM_ERROR,
                      "InfoRepoMulticastResponder::handle_input recv = %d\n",
                      n),
                     0);

  if (OpenDDS::DCPS::DCPS_debug_level > 0) {
    ACE_TCHAR addr[64];
    remote_addr.addr_to_string(addr, sizeof(addr));
    ACE_DEBUG((LM_DEBUG,
               "(%P|%t) Received multicast from %s.\n"
               "Service Name received : %C\n"
               "Port received : %u\n",
               addr,
               object_key,
               ACE_NTOHS(remote_port)));
  }

  // Grab the IOR table.
  CORBA::Object_var table_object =
    orb_->resolve_initial_references("IORTable");

  IORTable::Locator_var locator =
    IORTable::Locator::_narrow(table_object.in());

  if (CORBA::is_nil(locator.in())) {
    ACE_ERROR((LM_ERROR, ACE_TEXT("Nil IORTable\n")));

  }

  std::string ior;

  {
    CORBA::String_var ior_result;

    try {
      ior_result = locator->locate(object_key);

    } catch (const IORTable::NotFound&) {
      ACE_ERROR_RETURN((LM_ERROR,
                        "InfoRepoMulticastResponder::handle_input() Object key not found\n"),
                       0);
    }

    ior = ior_result;
  }

  // Reply to the multicast message.
  ACE_SOCK_Connector connector;
  ACE_INET_Addr peer_addr;
  ACE_SOCK_Stream stream;

  peer_addr.set(remote_addr);
  peer_addr.set_port_number(ACE_NTOHS(remote_port));

#if defined (ACE_HAS_IPV6)

  if (peer_addr.is_linklocal()) {
    // If this is one of our local linklocal interfaces this is not going
    // to work.
    // Creating a connection using such interface to the client listening
    // at the IPv6 ANY address is not going to work (I'm not quite sure why
    // but it probably has to do with the rather restrictive routing rules
    // for linklocal interfaces).
    // So we see if this is one of our local interfaces and if so create the
    // connection using the IPv6 loopback address instead.
    ACE_INET_Addr  peer_tmp(peer_addr);
    peer_tmp.set_port_number(static_cast<u_short>(0));
    ACE_INET_Addr* tmp = 0;
    size_t cnt = 0;
    int err = ACE::get_ip_interfaces(cnt, tmp);

    if (err == 0) {
      for (size_t i = 0; i < cnt; ++i) {
        if (peer_tmp == tmp[i]) {
          peer_addr.set(ACE_NTOHS(remote_port),
                        ACE_IPV6_LOCALHOST);
          break;
        }
      }

      delete[] tmp;
    }
  }

#endif /* ACE_HAS_IPV6 */

  if (OpenDDS::DCPS::DCPS_debug_level > 0) {
    ACE_TCHAR addr[64];
    peer_addr.addr_to_string(addr, sizeof(addr));
    ACE_DEBUG((LM_DEBUG,
               "(%P|%t) Replying to peer %s.\n",
               addr));
  }

  // Connect.
  if (connector.connect(stream, peer_addr) == -1)
    ACE_ERROR_RETURN((LM_ERROR, "InfoRepoMulticastResponder::connect failed\n"), 0);

  // Send the IOR back to the client.  (Send iovec, which contains ior
  // length as the first element, and ior itself as the second.)

  // Length of ior to be sent.
  CORBA::Short data_len =
    static_cast<CORBA::Short>(ACE_HTONS(ior.length() + 1));

  // Vector to be sent.
  const int cnt = 2;
  iovec iovp[cnt];

  // The length of ior to be sent.
  iovp[0].iov_base = (char *) &data_len;
  iovp[0].iov_len  = sizeof(CORBA::Short);

  // The ior.
  iovp[1].iov_base = const_cast<char*>(ior.c_str());
  iovp[1].iov_len  = static_cast<u_long>(ior.length() + 1);

  ssize_t result = stream.sendv_n(iovp, cnt);
  // Close the stream.
  stream.close();

  // Check for error.
  if (result == -1)
    ACE_ERROR_RETURN((LM_ERROR, "InfoRepoMulticastResponder::send failed\n"), 0);

  if (OpenDDS::DCPS::DCPS_debug_level > 0)
    ACE_DEBUG((LM_DEBUG,
               "(%P|%t) InfoRepoMulticastResponder::handle_input() ior: <%C>\n"
               "sent to %C:%u.\n"
               "result from send = %d\n",
               ior.c_str(),
               peer_addr.get_host_name(),
               peer_addr.get_port_number(),
               result));

  return 0;
}
示例#6
0
int CRtpPacket::ParsePacket
(
    char*     pRtpData, 
    unsigned int   ulLen
)
{
    if (NULL == pRtpData)
    {
        //BP_RUN_LOG_ERR(UNDEF_ERRCODE, "Rtp packet parse fail rtp data is null."," ");
        return NRU_FAIL;
    }
 
    // 不能小于固定头的长度, 且不能超过2000 (暂定)
    if (ulLen < sizeof(RTP_FIXED_HEADER)
        || RTP_VALID_LEN < ulLen)
    {
        //BP_RUN_LOG_ERR(UNDEF_ERRCODE, "Rtp packet parse fail rtp data.","len=%u is shorter than fixed head[%d] len.",			ulLen, sizeof(RTP_FIXED_HEADER));
        return NRU_FAIL;
    }
    m_pRtpData = (char*)pRtpData;
    m_ulPacketLen = ulLen;

    // 先指定固定头
    m_pFixedHead = (RTP_FIXED_HEADER*)(void*)m_pRtpData;

    unsigned int ulHeadLen = sizeof(RTP_FIXED_HEADER) + m_pFixedHead->csrc_len * RTP_CSRC_LEN;
    if (ulLen < ulHeadLen)
    {
        //BP_RUN_LOG_ERR(UNDEF_ERRCODE, "Rtp packet parse fail rtp data len is shorter than fixed head len."," ");
        return NRU_FAIL;
    }

    // 检查版本号
    if (NRU_SUCCESS != CheckVersion())
    {
        //BP_RUN_LOG_ERR(UNDEF_ERRCODE, "Rtp packet parse fail check version fail."," ");
        return NRU_FAIL;
    }

    //检查是否有填充数据
    if (1 == m_pFixedHead->padding) 		
    {		
		if (m_ulPacketLen > (unsigned int)pRtpData[ulLen - 1]) //lint !e571
		{
			m_ulPacketLen -= pRtpData[ulLen - 1];//lint !e737
		}
		else 
		{
			//BP_RUN_LOG_WAR("Rtp packet has padding data, but padding data len illegal.", 				"packet len=%u padding data len=%u", m_ulPacketLen, pRtpData[ulLen - 1]);
		}
    }

    m_ulFixedHeadLen = ulHeadLen;
    
    // 判断是否有扩展头
    if (1 != m_pFixedHead->extension)
    {
        // 没有扩展头,直接返回
        m_ulHeadLen = ulHeadLen;
        return NRU_SUCCESS;
    }

    //m_ulFixedHeadLen = ulHeadLen;
    if (ulLen < ulHeadLen + sizeof(RTP_EXTEND_HEADER))
    {
        //BP_RUN_LOG_ERR(UNDEF_ERRCODE, "Rtp packet parse fail packet len is too short to contain extend head."," ");
        return NRU_FAIL;
    }

    // 指定扩展头
    m_pExtHead = (RTP_EXTEND_HEADER*)(void*)(m_pRtpData + ulHeadLen);

    // 有扩展头,判断包的长度是否足够包含扩展头
    ulHeadLen += sizeof(RTP_EXTEND_HEADER) + ACE_NTOHS(m_pExtHead->usLength) * RTP_EXTEND_PROFILE_LEN;
    if (ulLen < ulHeadLen)
    {
        //BP_RUN_LOG_ERR(UNDEF_ERRCODE, "Rtp packet parse fail packet len is too short."," ");
        return NRU_FAIL;
    }

    if (m_pExtHead->usProfile == ACE_HTONS(0x4857))
    {     
        m_pExtData = (RTP_EXTENSION_DATA_S*)(void*)(m_pRtpData + m_ulFixedHeadLen + sizeof(RTP_EXTEND_HEADER));

        //根据扩展头长度判断是否前端传来的rtp扩展头,以及是否含有补齐信息字段.swx164794 add. 2013-03-09
        if (sizeof(RTP_EXTENSION_DATA_S_EX) == ACE_NTOHS(m_pExtHead->usLength)* RTP_EXTEND_PROFILE_LEN)
        {
            m_pExtDataHaveFillIn = (RTP_EXTENSION_DATA_S_EX*)(void*)(m_pRtpData + m_ulFixedHeadLen + sizeof(RTP_EXTEND_HEADER));
        }
        else if (sizeof(RTP_EXTENSION_DATA_MU_S) == ACE_NTOHS(m_pExtHead->usLength) * RTP_EXTEND_PROFILE_LEN)
        {
            m_pExtDataHaveFillIn = (RTP_EXTENSION_DATA_S_EX*)(void*)(m_pRtpData + m_ulFixedHeadLen + sizeof(RTP_EXTEND_HEADER));
            m_pMuExtData = (RTP_EXTENSION_DATA_MU_S*)(void*)(m_pRtpData + m_ulFixedHeadLen + sizeof(RTP_EXTEND_HEADER));
        }    
    }

    // 至此,所有的头长度已经计算完毕了
    m_ulHeadLen = ulHeadLen;

    return NRU_SUCCESS;
}