rnb_err_t
RNBSocket::Connect (const char *host, uint16_t port)
{
    Disconnect (false);

    // Create the socket
    m_fd = ::socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (m_fd == -1)
        return rnb_err;
    
    // Enable local address reuse
    SetSocketOption (m_fd, SOL_SOCKET, SO_REUSEADDR, 1);
    
    struct sockaddr_in sa;
    ::memset (&sa, 0, sizeof (sa));
    sa.sin_family = AF_INET;
    sa.sin_port = htons (port);
    
    if (!ResolveIPV4HostName(host, sa.sin_addr.s_addr))
    {
        DNBLogThreaded("error: failed to resolve host '%s'", host);
        Disconnect (false);
        return rnb_err;
    }
    
    if (-1 == ::connect (m_fd, (const struct sockaddr *)&sa, sizeof(sa)))
    {
        Disconnect (false);
        return rnb_err;
    }
    
    // Keep our TCP packets coming without any delays.
    SetSocketOption (m_fd, IPPROTO_TCP, TCP_NODELAY, 1);
    return rnb_success;
}
Exemple #2
0
rnb_err_t
RNBSocket::Connect (const char *host, uint16_t port)
{
    Disconnect (false);

    // Create the socket
    m_fd = ::socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (m_fd == -1)
        return rnb_err;
    
    // Enable local address reuse
    SetSocketOption (m_fd, SOL_SOCKET, SO_REUSEADDR, 1);
    
    struct sockaddr_in sa;
    ::memset (&sa, 0, sizeof (sa));
    sa.sin_family = AF_INET;
    sa.sin_port = htons (port);
    
    if (host == NULL)
        host = "localhost";

    int inet_pton_result = ::inet_pton (AF_INET, host, &sa.sin_addr);
    
    if (inet_pton_result <= 0)
    {
        struct hostent *host_entry = gethostbyname (host);
        if (host_entry)
        {
            std::string host_str (::inet_ntoa (*(struct in_addr *)*host_entry->h_addr_list));
            inet_pton_result = ::inet_pton (AF_INET, host_str.c_str(), &sa.sin_addr);
            if (inet_pton_result <= 0)
            {
                Disconnect (false);
                return rnb_err;
            }
        }
    }
    
    if (-1 == ::connect (m_fd, (const struct sockaddr *)&sa, sizeof(sa)))
    {
        Disconnect (false);
        return rnb_err;
    }
    
    // Keep our TCP packets coming without any delays.
    SetSocketOption (m_fd, IPPROTO_TCP, TCP_NODELAY, 1);
    return rnb_success;
}
Exemple #3
0
MPIPTVSOURCE_API int SetAndCheckSocketOption(CLogger *logger, const TCHAR *protocolName, const TCHAR *functionName, const TCHAR *optionName, SOCKET s, int level, int optname, const char *optval, int optlen)
{
  int result = SetSocketOption(logger, protocolName, functionName, optionName, s, level, optname, optval, optlen);

  if (result == 0)
  {
    // option correctly set, now check it
    int valLen = optlen;
    ALLOC_MEM_DEFINE_SET(val, char, optlen, 0);
    result = (val == NULL) ? E_OUTOFMEMORY : 0;
    if (result == 0)
    {
      result = GetSocketOption(logger, protocolName, functionName, optionName, s, level, optname, val, &valLen);
      if (result == 0)
      {
        // successfully retrieved value
        if (optlen == valLen)
        {
          result = (memcmp(optval, val, optlen) == 0) ? 0 : (-1);
        }
      }
    }

    FREE_MEM(val);
  }
Exemple #4
0
MPIPTVSOURCE_API int JoinMulticastGroupIPv6(CLogger *logger, const TCHAR *protocolName, SOCKET m_socket, const struct sockaddr_in6 *local, CParameterCollection *parameters)
{
  int result = 0;
  struct ipv6_mreq gr6;
  memset(&gr6, 0, sizeof(gr6));
  gr6.ipv6mr_interface = local->sin6_scope_id;
  memcpy(&gr6.ipv6mr_multiaddr, &local->sin6_addr, 16);

  if (parameters != NULL)
  {
    // we have set some parameters
    // get interface parameter
    PCParameter networkInterfaceParameter = parameters->GetParameter(INTERFACE_PARAMETER_NAME, true);
    if (networkInterfaceParameter != NULL)
    {
      ULONG interfaceId = GetInterfaceId(logger, protocolName, networkInterfaceParameter->GetValue(), local->sin6_family);
      result = (interfaceId != 0) ? 0 : (-1);
      if (result == 0)
      {
        gr6.ipv6mr_interface = interfaceId;
        logger->Log(LOGGER_INFO, _T("%s: %s: try to bind on interface '%s', id: %u"), protocolName, METHOD_JOIN_MULTICAST_GROUP_IPV6_NAME, networkInterfaceParameter->GetValue(), gr6.ipv6mr_interface);
      }
      else
      {
        logger->Log(LOGGER_ERROR, METHOD_MESSAGE_FORMAT, protocolName, METHOD_JOIN_MULTICAST_GROUP_IPV6_NAME, _T("cannot get interface ID"));
      }
    }
  }

  logger->Log(LOGGER_INFO, METHOD_MESSAGE_FORMAT, protocolName, METHOD_JOIN_MULTICAST_GROUP_IPV6_NAME, _T("IPV6_JOIN_GROUP multicast request"));
  result = (SetSocketOption(logger, protocolName, METHOD_JOIN_MULTICAST_GROUP_IPV6_NAME, _T("IPV6_JOIN_GROUP"), m_socket, IPPROTO_IPV6, IPV6_JOIN_GROUP, (char *)&gr6, sizeof(gr6)) == 0) ? 0 : (-1);

  logger->Log(LOGGER_INFO, (result == 0) ? METHOD_END_FORMAT : METHOD_END_FAIL_FORMAT, protocolName, METHOD_JOIN_MULTICAST_GROUP_IPV6_NAME);
  return result;
}
Exemple #5
0
void NetIO::Init()
{
	listen_fd = socket(AF_INET, SOCK_STREAM, 0);
	if(listen_fd == -1)
		error("Error %d occured in socket()", errno);

	if(is_server)
	{
		if(!SetSocketOption(listen_fd, SOL_SOCKET, SO_REUSEADDR, 1))
			error("Error %d occured in SetSocketOption(listen_fd, SO_REUSEADDR)", errno);
	}

	sockaddr_in servaddr;
	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_port = htons(port);
	if(ip_address != NULL)
	{
		if(inet_pton(AF_INET, ip_address, &servaddr.sin_addr) == -1)
			error("Error %d occured in inet_pton(%s)", errno, ip_address);
	}
	else
		servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

	if(bind(listen_fd, (sockaddr*) &servaddr, sizeof(servaddr)) == -1)
		error("Error %d occured in bind()", errno);
}
void CSocketItems::ApplyBonusOptions(LPOBJ lpObj)
{
	BYTE btBonusOption = 0;
	_SOCKET_BONUS_DATA* lpBonusOption = NULL;

	for(int i = 0; i < INVETORY_WEAR_SIZE; i++)
	{
		if( IsSocketItem(&lpObj->pInventory[i]) == FALSE )
			continue;

		btBonusOption = lpObj->pInventory[i].m_SocketBonus;

		if( btBonusOption == 0xFF ||
			btBonusOption == 0xFE )
			continue;

		lpBonusOption = GetBonusOption(btBonusOption);

		if( lpBonusOption == NULL )
			continue;

		LogAddTD("[SocketItem] [%s][%s] Set Bonus Socket Option - OptionIndex : %d, EffectType : %d, OptionType : %d, OptionValue : %d",
			lpObj->AccountID,lpObj->Name,lpBonusOption->btIndex,lpBonusOption->btEffectType,lpBonusOption->btOptionType,lpBonusOption->btOptionValue);
		SetSocketOption(lpObj,2,lpBonusOption->btEffectType,lpBonusOption->btOptionType,lpBonusOption->btOptionValue);
	}
}
int CSocketItems::ApplySocketOptions(LPOBJ lpObj)
{
	int OptionCount = 0;
	BYTE btSocketOption = 0;
	BYTE btOption = 0;
	BYTE btLevel = 0;

	_SOCKET_SPHERE_OPTION tmpSphere;

	for(int i = 0; i < INVETORY_WEAR_SIZE; i++)
	{
		if( IsSocketItem(&lpObj->pInventory[i]) == FALSE )
			continue;

		for(int n = 0; n < MAX_SOCKET_COUNT; n++)
		{
			btSocketOption = lpObj->pInventory[i].m_SocketOption[n];

			if( btSocketOption == 0xFF ||
				btSocketOption == 0xFE )
				continue;

			btOption = btSocketOption%50;
			btLevel = (btSocketOption-btOption)/50+1;

			if( IsOptionSet(&tmpSphere,btOption,btLevel) == FALSE )
				continue;

			SetSocketOption(lpObj,TRUE,btOption,tmpSphere.btIncType,tmpSphere.wSphereValue);
			OptionCount++;
		}
	}
return OptionCount;
}
Exemple #8
0
////////////////////////////////////////////////////////////////////////////////
//	函数名:SOCKET Accept(
//				struct sockaddr * pSocketAddr,
//				LPINT nAddrLen,
//				DWORD dwTimeout /*= DEFAULT_ACCEPT_TIMEOUT*/ )
//	用  途:接受套接字连接
//	对全局变量的影响:无
//	参  数:
//		pSocketAddr : SOCKET地址
//		nAddrLen    : 地址参数的长度
//		dwTimeout   : 超时
//	返回值:SOCKET
////////////////////////////////////////////////////////////////////////////////
SOCKET CBufSocket::Accept(struct sockaddr * pSocketAddr, LPINT nAddrLen,DWORD dwTimeout /*= DEFAULT_ACCEPT_TIMEOUT*/)
{
    HANDLE hAcceptEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    if (hAcceptEvent == NULL)
    {
        SetLastError( (INT)GetLastError() );
        return (INVALID_SOCKET);
    }

    // 注册FD_ACCEPT事件
    if( WSAEventSelect(m_hSocket, (WSAEVENT) hAcceptEvent, FD_ACCEPT) == SOCKET_ERROR)
    {
        CloseHandle(hAcceptEvent);
        SetLastError( WSAGetLastError() );
        return (INVALID_SOCKET);
    }

    SOCKET hSocketAccept = WSAAccept(m_hSocket, pSocketAddr, nAddrLen, NULL, 0);
    INT	   nConnectError = WSAGetLastError();

    if ((hSocketAccept == INVALID_SOCKET) && (nConnectError == WSAEWOULDBLOCK))
    {

        // 阻塞
        DWORD dwWaitResult = WSAWaitForMultipleEvents(1, &hAcceptEvent, TRUE,dwTimeout, TRUE);

        if (dwWaitResult == WSA_WAIT_EVENT_0)
        {
            //////////////////////////////////////////////////////////////
            ///	注意:即使 dwWaitResult == WSA_WAIT_EVENT0 ,也应该
            ///			进一步检查网络是否发生错误
            ///////////////////////////////////////////////////////////////
            WSANETWORKEVENTS NetEvent;
            if(WSAEnumNetworkEvents(m_hSocket,hAcceptEvent,&NetEvent) == SOCKET_ERROR)
                SetLastError( WSAGetLastError() );
            else if(NetEvent.iErrorCode[FD_ACCEPT_BIT] !=0 )	// 发生错误
                SetLastError( NetEvent.iErrorCode[FD_ACCEPT_BIT] );
            else
                hSocketAccept = WSAAccept(m_hSocket, pSocketAddr, nAddrLen, NULL, 0);
        }
        else
            SetLastError( WSAGetLastError() );
    }

    // 注销网络事件
    WSAEventSelect( m_hSocket, (WSAEVENT) hAcceptEvent, 0);
    CloseHandle(hAcceptEvent);

    if (hSocketAccept != INVALID_SOCKET)
    {
        // 设置套接字的属性为地址可重用并且为非阻塞的
        if ( !Block(hSocketAccept, 0) || !SetSocketOption(hSocketAccept) )
        {
            closesocket(hSocketAccept);
            return (INVALID_SOCKET);
        }
    }
    return (hSocketAccept);
}
Exemple #9
0
void NetIO::Accept(WorkersPool *workers)
{
	if(listen_fd == 0)
		Init();

	if(!SetSocketOption(listen_fd, SOL_SOCKET, SO_RCVBUF, MAX_BUFF_SIZE))
		error("Error %d occured in SetSocketOption(listen_fd, SO_RCVBUF, %d)", errno, MAX_BUFF_SIZE);

	if(!SetSocketOption(listen_fd, SOL_SOCKET, SO_SNDBUF, MAX_BUFF_SIZE))
		error("Error %d occured in SetSocketOption(listen_fd, SO_SNDBUF, %d)", errno, MAX_BUFF_SIZE);

	if(listen(listen_fd, -1) == -1)
		error("Error %d occured in listen(listen_fd)", errno);

	while(true)
	{
		int conn_fd = accept(listen_fd, (sockaddr*) NULL, NULL);
		if(terminated)
			return;

		if(conn_fd == -1)
		{
			if(errno == EINTR || errno == ECONNABORTED)
				continue;
			error("Error %d occured in accept()", errno);
		}

		if(!AddFcntl(conn_fd, O_NONBLOCK))
			error("Error %d occured in AddFcntl(conn_fd, O_NONBLOCK)", errno);

		if(!SetSocketOption(conn_fd, SOL_SOCKET, SO_KEEPALIVE, 1))
			error("Error %d occured in SetSocketOption(conn_fd, SO_KEEPALIVE, 1)", errno);

		if(!SetSocketOption(conn_fd, IPPROTO_TCP, TCP_NODELAY, 1))
			error("Error %d occured in SetSocketOption(conn_fd, TCP_NODELAY, 1)", errno);

		workers->Accept(conn_fd);
	}
}
Exemple #10
0
bool CSocket::SetNoDelay(void)
{
    m_enError = SOCK_OK;
    m_strErrorMsg.clear();
        
    if (m_enType == IP_TCP && m_enType == UN_TCP) {
        m_enError = SOCK_TYPE;
        m_strErrorMsg = "socket type invalied, only TCP";
        return false;
    }

    int optval = 1;
    return SetSocketOption(IPPROTO_TCP, TCP_NODELAY, (void *)&optval, sizeof(optval));    
}
void CSocketItems::ApplySetOptions(LPOBJ lpObj)
{
	BYTE OpCount[8];
	BYTE btGroup = 0;
	BYTE btCount = 0;

	memset(&OpCount,0,sizeof(OpCount));

	for(int i = 0; i < 35; i++)
	{
		btGroup  = GetOptionGroup(lpObj->m_SocketOptions[i].btOption);

		if( btGroup == NULL )
			break;

		OpCount[-1+btGroup] += lpObj->m_SocketOptions[i].Count;
	}

	for(int n = 0; n < MAX_SET_OPTION; n++)
	{
		for(int i = 0; i < MAX_SEED_TYPE; i++)
		{
			if( this->m_SetOption[n].SeedCount[i] <= OpCount[i] )
			{
				btCount++;
			}
		}

		if( btCount == 6 )
		{
			SetSocketOption(lpObj,3,this->m_SetOption[n].btEffect,this->m_SetOption[n].btIncType,this->m_SetOption[n].btIncValue);
		}

		btCount = 0;
	}
}
Exemple #12
0
MPIPTVSOURCE_API int UnsubscribeFromMulticastGroup(CLogger *logger, const TCHAR *protocolName, SOCKET m_socket, const struct sockaddr *source, socklen_t sourceLen, const struct sockaddr *local, socklen_t localLen, CParameterCollection *parameters)
{
  int result = 0;
  int level;
  ULONG iid = 0;

  if (parameters != NULL)
  {
    // we have set some parameters
    // get interface parameter
    PCParameter networkInterfaceParameter = parameters->GetParameter(INTERFACE_PARAMETER_NAME, true);
    if (networkInterfaceParameter != NULL)
    {
      ULONG interfaceId = GetInterfaceId(logger, protocolName, networkInterfaceParameter->GetValue(), local->sa_family);
      result = (interfaceId != 0) ? 0 : (-1);

      if (result == 0)
      {
        iid = interfaceId;
        logger->Log(LOGGER_INFO, _T("%s: %s: try to bind on interface '%s', id: %u"), protocolName, METHOD_UNSUBSCRIBE_FROM_MULTICAST_GROUP_NAME, networkInterfaceParameter->GetValue(), iid);
      }
      else
      {
        logger->Log(LOGGER_ERROR, METHOD_MESSAGE_FORMAT, protocolName, METHOD_UNSUBSCRIBE_FROM_MULTICAST_GROUP_NAME, _T("cannot get interface ID"));
      }
    }
  }

  if (result == 0)
  {
    switch (local->sa_family)
    {
    case AF_INET6:
      level = IPPROTO_IPV6;
      break;
    case AF_INET:
      level = IPPROTO_IP;
      break;
    default:
      logger->Log(LOGGER_ERROR, _T("%s: %s: not supported internet family: %d"), protocolName, METHOD_UNSUBSCRIBE_FROM_MULTICAST_GROUP_NAME, local->sa_family);
      result = -1;
    }
  }

  if (result == 0)
  {
    if (source != NULL)
    {
      switch (source->sa_family)
      {
      case AF_INET6:
        if (memcmp(&((const struct sockaddr_in6 *)source)->sin6_addr, &in6addr_any, sizeof(in6addr_any)) == 0)
        {
          source = NULL;
        }
        break;
      case AF_INET:
        if (((const struct sockaddr_in *)source)->sin_addr.s_addr == INADDR_ANY)
        {
          source = NULL;
        }
        break;
      }
    }

    union
    {
      struct group_req gr;
      struct group_source_req gsr;
    } opt;
    socklen_t optlen;

    memset(&opt, 0, sizeof (opt));
    if (source != NULL)
    {
      if ((localLen > sizeof (opt.gsr.gsr_group)) || (sourceLen > sizeof (opt.gsr.gsr_source)))
      {
        result = -1;
      }

      if (result == 0)
      {
        opt.gsr.gsr_interface = iid;
        memcpy(&opt.gsr.gsr_source, source, sourceLen);
        memcpy(&opt.gsr.gsr_group, local, localLen);
        optlen = sizeof(opt.gsr);
      }
    }
    else
    {
      if (localLen > sizeof (opt.gr.gr_group))
      {
        result = -1;
      }

      if (result == 0)
      {
        opt.gr.gr_interface = iid;
        memcpy(&opt.gr.gr_group, local, localLen);
        optlen = sizeof(opt.gr);
      }
    }

    if (result == 0)
    {
      logger->Log(LOGGER_INFO, METHOD_MESSAGE_FORMAT, protocolName, METHOD_UNSUBSCRIBE_FROM_MULTICAST_GROUP_NAME, (source != NULL) ? _T("multicast source group leave request") : _T("multicast group leave request"));
      result = (SetSocketOption(logger, protocolName, METHOD_UNSUBSCRIBE_FROM_MULTICAST_GROUP_NAME, (source != NULL) ? _T("MCAST_LEAVE_SOURCE_GROUP") : _T("MCAST_LEAVE_GROUP"), m_socket, level, (source != NULL) ? MCAST_LEAVE_SOURCE_GROUP : MCAST_LEAVE_GROUP, (char *)&opt, optlen) == 0) ? 0 : (-1);

      if (result != 0)
      {
        result = 0;
        logger->Log(LOGGER_INFO, METHOD_MESSAGE_FORMAT, protocolName, METHOD_UNSUBSCRIBE_FROM_MULTICAST_GROUP_NAME, (source != NULL) ? _T("multicast source group leave request not successful") : _T("multicast group leave request not successful"));

        // fallback to IPv-specific APIs
        if ((source != NULL) && (source->sa_family != local->sa_family))
        {
          logger->Log(LOGGER_ERROR, METHOD_MESSAGE_FORMAT, protocolName, METHOD_UNSUBSCRIBE_FROM_MULTICAST_GROUP_NAME, _T("source and local internet address family not same"));
          result = -1;
        }

        if (result == 0)
        {
          switch (local->sa_family)
          {
          case AF_INET:
            if ((localLen < sizeof (struct sockaddr_in)) || ((source != NULL) && (sourceLen < sizeof (struct sockaddr_in))))
            {
              result = -1;
            }

            if (result == 0)
            {
              result = LeaveMulticastGroupIPv4(logger, protocolName, m_socket, (const struct sockaddr_in *)source, (const struct sockaddr_in *)local, parameters);
            }
            break;
          case AF_INET6:
            if ((localLen < sizeof (struct sockaddr_in6)) || ((source != NULL) && (sourceLen < sizeof (struct sockaddr_in6))))
            {
              result = -1;
            }

            if (result == 0)
            {
              result = LeaveMulticastGroupIPv6(logger, protocolName, m_socket, (const struct sockaddr_in6 *)local, parameters);
            }
            break;
          }

          if (result != 0)
          {
            logger->Log(LOGGER_ERROR, METHOD_MESSAGE_FORMAT, protocolName, METHOD_UNSUBSCRIBE_FROM_MULTICAST_GROUP_NAME, _T("multicast group leave error"));
            if (source != NULL)
            {
              logger->Log(LOGGER_WARNING, METHOD_MESSAGE_FORMAT, protocolName, METHOD_UNSUBSCRIBE_FROM_MULTICAST_GROUP_NAME, _T("trying another leave method"));
              result = UnsubscribeFromMulticastGroup(logger, protocolName, m_socket, NULL, 0, local, localLen, parameters);
            }
          }
        }
      }
    }
  }

  logger->Log(LOGGER_INFO, (result == 0) ? METHOD_END_FORMAT : METHOD_END_FAIL_FORMAT, protocolName, METHOD_UNSUBSCRIBE_FROM_MULTICAST_GROUP_NAME);
  return result;
}
Exemple #13
0
MPIPTVSOURCE_API int LeaveMulticastGroupIPv4(CLogger *logger, const TCHAR *protocolName, SOCKET m_socket, const struct sockaddr_in *source, const struct sockaddr_in *local, CParameterCollection *parameters)
{
  ADDRINFOT *networkInterface = NULL;
  ADDRINFOT hints;
  hints.ai_family = local->sin_family;
  hints.ai_socktype = SOCK_DGRAM;
  hints.ai_protocol = IPPROTO_UDP;
  hints.ai_flags = AI_PASSIVE;
  int result = 0;

  if (parameters != NULL)
  {
    // we have set some parameters
    // get interface parameter
    PCParameter networkInterfaceParameter = parameters->GetParameter(INTERFACE_PARAMETER_NAME, true);
    if (networkInterfaceParameter != NULL)
    {
      TCHAR *networkInterfaceAddress = GetInterfaceAddress(logger, protocolName, networkInterfaceParameter->GetValue(), local->sin_family);
      int errorCode = GetIpAddress(networkInterfaceAddress, 0, &networkInterface, &hints);
      if (errorCode != 0)
      {
        logger->Log(LOGGER_ERROR, _T("%s: %s: getaddrinfo() for network interface error: %d"), protocolName, METHOD_LEAVE_MULTICAST_GROUP_IPV4_NAME, errorCode);
        result = -1;
      }
      if (result == 0)
      {
        logger->Log(LOGGER_INFO, _T("%s: %s: try to bind on interface '%s', address: %s"), protocolName, METHOD_LEAVE_MULTICAST_GROUP_IPV4_NAME, networkInterfaceParameter->GetValue(), networkInterfaceAddress);
      }
      FREE_MEM(networkInterfaceAddress);
    }
  }

  if (result == 0)
  {
    union
    {
      struct ip_mreq gr4;
      struct ip_mreq_source gsr4;
    } opt;
    int cmd;
    struct in_addr id;

    if (networkInterface != NULL)
    {
      id = ((sockaddr_in *)networkInterface->ai_addr)->sin_addr;
    }
    else
    {
      id.s_addr = INADDR_ANY;
    }
    socklen_t optlen;

    memset(&opt, 0, sizeof(opt));
    if (source != NULL)
    {
      cmd = IP_DROP_SOURCE_MEMBERSHIP;
      opt.gsr4.imr_multiaddr = local->sin_addr;
      opt.gsr4.imr_sourceaddr = source->sin_addr;
      opt.gsr4.imr_interface = id;
      optlen = sizeof (opt.gsr4);
    }
    else
    {
      cmd = IP_DROP_MEMBERSHIP;
      opt.gr4.imr_multiaddr = local->sin_addr;
      opt.gr4.imr_interface = id;
      optlen = sizeof(opt.gr4);
    }

    logger->Log(LOGGER_INFO, METHOD_MESSAGE_FORMAT, protocolName, METHOD_LEAVE_MULTICAST_GROUP_IPV4_NAME, (source != NULL) ? _T("IP_DROP_SOURCE_MEMBERSHIP multicast request") : _T("IP_DROP_MEMBERSHIP multicast request"));
    result = (SetSocketOption(logger, protocolName, METHOD_LEAVE_MULTICAST_GROUP_IPV4_NAME, (source != NULL) ? _T("IP_DROP_SOURCE_MEMBERSHIP") : _T("IP_DROP_MEMBERSHIP"), m_socket, IPPROTO_IP, cmd, (char *)&opt, optlen) == 0) ? 0 : (-1);
  }

  if (networkInterface != NULL)
  {
    FreeAddrInfo(networkInterface);
    networkInterface = NULL;
  }

  logger->Log(LOGGER_INFO, (result == 0) ? METHOD_END_FORMAT : METHOD_END_FAIL_FORMAT, protocolName, METHOD_LEAVE_MULTICAST_GROUP_IPV4_NAME);
  return result;
}
Exemple #14
0
////////////////////////////////////////////////////////////////////////////////
//	函数名:BOOL Create(
//				INT nAddressFamily /*= AF_INET*/,
//				INT nType /*= SOCK_STREAM*/,
//				INT nProtocol /*= 0*/,
//				INT nBufferSize /*= DEFAULT_BUFFER_SIZE*/,
//				SOCKET hSocket /*= INVALID_SOCKET*/,
//				DWORD dwFlags /*= WSA_FLAG_OVERLAPPED*/ )
//	用  途:创建SOCKET和BSD结构
//	对全局变量的影响:无
//	参  数:
//		nAddressFamily : SOCKET地址家族
//		nType          : SOCKET类型
//		nProtocol      : SOCKET采用的协议
//		nBufferSize    : 缓冲区的大小
//		hSocket        : 类实例绑定的套接字
//		dwFlags        : 套接字的属性
//	返回值:BOOL
////////////////////////////////////////////////////////////////////////////////
BOOL	CBufSocket::Create(	INT		nAddressFamily	/*= AF_INET*/,
                            INT		nType			/*= SOCK_STREAM*/,
                            INT		nProtocol		/*= 0*/,
                            INT		nBufferSize		/*= DEFAULT_BUFFER_SIZE*/,
                            SOCKET	hSocket			/*= INVALID_SOCKET*/,
                            DWORD	dwFlags			/*= WSA_FLAG_OVERLAPPED*/)
{
    if (INVALID_SOCKET == hSocket)
    {
        m_hSocket = WSASocket(nAddressFamily, nType, nProtocol, NULL,0,dwFlags);

        if (INVALID_SOCKET == m_hSocket)
        {
            SetLastError( WSAGetLastError() ); //为何获得了还需要设置
            return FALSE;
        }
    }
    else
    {
        m_hSocket = hSocket;
    }

    if (SOCK_STREAM == nType)   //TCP
    {
        //设置套接字选项
        if (!SetSocketOption(m_hSocket))    //设置属性失败
        {
            Close(TRUE);
            m_hSocket = INVALID_SOCKET;
            return FALSE;
        }

        //创建BSD

        //分配内存
        m_pBSD = new BSD;

        if (NULL == m_pBSD)
        {
            Close(TRUE);
            return FALSE;
        }

        CHAR *pszBuffer = new CHAR[nBufferSize];
        if (NULL == pszBuffer)
        {
            Close(TRUE);

            delete m_pBSD;
            m_pBSD = NULL;

            return FALSE;
        }

        CHAR *pszBufferRecv = new CHAR[nBufferSize];
        if (NULL == pszBufferRecv)
        {
            Close(TRUE);

            delete m_pBSD;
            m_pBSD = NULL;

            delete pszBuffer;

            return FALSE;
        }

        // 设置结构成员
        ZeroMemory(m_pBSD, sizeof(BSD));
        ZeroMemory(pszBuffer, nBufferSize);
        ZeroMemory(pszBufferRecv, nBufferSize);

        m_pBSD->hSocket			= m_hSocket;
        m_pBSD->nBufferSize		= nBufferSize;
        m_pBSD->pszBuffer		= pszBuffer;
        m_pBSD->pszBufferRecv	= pszBufferRecv;
        m_pBSD->nBytesInBuffer	= 0;
        m_pBSD->nReadIndex		= 0;
        m_pBSD->nBufferIndex	= 0;
    }
    else	// UDP
    {
        m_pBSD = NULL;
    }

    return TRUE;
}
Exemple #15
0
rnb_err_t
RNBSocket::Listen (in_port_t port, PortBoundCallback callback, const void *callback_baton)
{
    //DNBLogThreadedIf(LOG_RNB_COMM, "%8u RNBSocket::%s called", (uint32_t)m_timer.ElapsedMicroSeconds(true), __FUNCTION__);
    // Disconnect without saving errno
    Disconnect (false);

    DNBError err;
    int listen_fd = ::socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (listen_fd == -1)
        err.SetError(errno, DNBError::POSIX);

    if (err.Fail() || DNBLogCheckLogBit(LOG_RNB_COMM))
        err.LogThreaded("::socket ( domain = AF_INET, type = SOCK_STREAM, protocol = IPPROTO_TCP ) => socket = %i", listen_fd);

    if (err.Fail())
        return rnb_err;

    // enable local address reuse
    SetSocketOption (listen_fd, SOL_SOCKET, SO_REUSEADDR, 1);

    struct sockaddr_in sa;
    ::memset (&sa, 0, sizeof sa);
    sa.sin_len = sizeof sa;
    sa.sin_family = AF_INET;
    sa.sin_port = htons (port);
    sa.sin_addr.s_addr = htonl (INADDR_ANY);

    int error = ::bind (listen_fd, (struct sockaddr *) &sa, sizeof(sa));
    if (error == -1)
        err.SetError(errno, DNBError::POSIX);

    if (err.Fail() || DNBLogCheckLogBit(LOG_RNB_COMM))
        err.LogThreaded("::bind ( socket = %i, (struct sockaddr *) &sa, sizeof(sa)) )", listen_fd);

    if (err.Fail())
    {
        ClosePort (listen_fd, false);
        return rnb_err;
    }

    if (callback && port == 0)
    {
        // We were asked to listen on port zero which means we
        // must now read the actual port that was given to us 
        // as port zero is a special code for "find an open port
        // for me".
        socklen_t sa_len = sizeof (sa);
        if (getsockname(listen_fd, (struct sockaddr *)&sa, &sa_len) == 0)
        {
            port = ntohs (sa.sin_port);
            callback (callback_baton, port);
        }
    }

    error = ::listen (listen_fd, 1);
    if (error == -1)
        err.SetError(errno, DNBError::POSIX);

    if (err.Fail() || DNBLogCheckLogBit(LOG_RNB_COMM))
        err.LogThreaded("::listen ( socket = %i, backlog = 1 )", listen_fd);

    if (err.Fail())
    {
        ClosePort (listen_fd, false);
        return rnb_err;
    }

    m_fd = ::accept (listen_fd, NULL, 0);
    if (m_fd == -1)
        err.SetError(errno, DNBError::POSIX);

    if (err.Fail() || DNBLogCheckLogBit(LOG_RNB_COMM))
        err.LogThreaded("::accept ( socket = %i, address = NULL, address_len = 0 )", listen_fd);

    ClosePort (listen_fd, false);

    if (err.Fail())
    {
        return rnb_err;
    }
    else
    {
        // Keep our TCP packets coming without any delays.
        SetSocketOption (m_fd, IPPROTO_TCP, TCP_NODELAY, 1);
    }

    return rnb_success;
}
rnb_err_t
RNBSocket::Listen (const char *listen_host, uint16_t port, PortBoundCallback callback, const void *callback_baton)
{
    //DNBLogThreadedIf(LOG_RNB_COMM, "%8u RNBSocket::%s called", (uint32_t)m_timer.ElapsedMicroSeconds(true), __FUNCTION__);
    // Disconnect without saving errno
    Disconnect (false);

    // Now figure out the hostname that will be attaching and palce it into
    struct sockaddr_in listen_addr;
    ::memset (&listen_addr, 0, sizeof listen_addr);
    listen_addr.sin_len = sizeof listen_addr;
    listen_addr.sin_family = AF_INET;
    listen_addr.sin_port = htons (port);
    listen_addr.sin_addr.s_addr = INADDR_ANY;
    
    if (!ResolveIPV4HostName(listen_host, listen_addr.sin_addr.s_addr))
    {
        DNBLogThreaded("error: failed to resolve connecting host '%s'", listen_host);
        return rnb_err;
    }
    
    DNBError err;
    int listen_fd = ::socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (listen_fd == -1)
        err.SetError(errno, DNBError::POSIX);

    if (err.Fail() || DNBLogCheckLogBit(LOG_RNB_COMM))
        err.LogThreaded("::socket ( domain = AF_INET, type = SOCK_STREAM, protocol = IPPROTO_TCP ) => socket = %i", listen_fd);

    if (err.Fail())
        return rnb_err;

    // enable local address reuse
    SetSocketOption (listen_fd, SOL_SOCKET, SO_REUSEADDR, 1);

    struct sockaddr_in sa;
    ::memset (&sa, 0, sizeof sa);
    sa.sin_len = sizeof sa;
    sa.sin_family = AF_INET;
    sa.sin_port = htons (port);
    sa.sin_addr.s_addr = INADDR_ANY; // Let incoming connections bind to any host network interface (this is NOT who can connect to us)
    int error = ::bind (listen_fd, (struct sockaddr *) &sa, sizeof(sa));
    if (error == -1)
        err.SetError(errno, DNBError::POSIX);

    if (err.Fail() || DNBLogCheckLogBit(LOG_RNB_COMM))
        err.LogThreaded("::bind ( socket = %i, (struct sockaddr *) &sa, sizeof(sa)) )", listen_fd);

    if (err.Fail())
    {
        ClosePort (listen_fd, false);
        return rnb_err;
    }

    error = ::listen (listen_fd, 5);
    if (error == -1)
        err.SetError(errno, DNBError::POSIX);

    if (err.Fail() || DNBLogCheckLogBit(LOG_RNB_COMM))
        err.LogThreaded("::listen ( socket = %i, backlog = 1 )", listen_fd);

    if (err.Fail())
    {
        ClosePort (listen_fd, false);
        return rnb_err;
    }
    
    if (callback)
    {
        // We were asked to listen on port zero which means we
        // must now read the actual port that was given to us
        // as port zero is a special code for "find an open port
        // for me".
        if (port == 0)
        {
            socklen_t sa_len = sizeof (sa);
            if (getsockname(listen_fd, (struct sockaddr *)&sa, &sa_len) == 0)
            {
                port = ntohs (sa.sin_port);
                callback (callback_baton, port);
            }
        }
        else
        {
            callback (callback_baton, port);
        }
    }

    struct sockaddr_in accept_addr;
    ::memset (&accept_addr, 0, sizeof accept_addr);
    accept_addr.sin_len = sizeof accept_addr;

    bool accept_connection = false;

    // Loop until we are happy with our connection
    while (!accept_connection)
    {
        socklen_t accept_addr_len = sizeof accept_addr;
        m_fd = ::accept (listen_fd, (struct sockaddr *)&accept_addr, &accept_addr_len);

        if (m_fd == -1)
            err.SetError(errno, DNBError::POSIX);
        
        if (err.Fail() || DNBLogCheckLogBit(LOG_RNB_COMM))
            err.LogThreaded("::accept ( socket = %i, address = %p, address_len = %u )", listen_fd, &accept_addr, accept_addr_len);

        if (err.Fail())
            break;

        if (listen_addr.sin_addr.s_addr == INADDR_ANY)
            accept_connection = true;
        else
        {
            if (accept_addr_len == listen_addr.sin_len &&
                accept_addr.sin_addr.s_addr == listen_addr.sin_addr.s_addr)
            {
                accept_connection = true;
            }
            else
            {
                ::close (m_fd);
                m_fd = -1;
                const uint8_t *accept_ip = (const uint8_t *)&accept_addr.sin_addr.s_addr;
                const uint8_t *listen_ip = (const uint8_t *)&listen_addr.sin_addr.s_addr;
                ::fprintf (stderr,
                           "error: rejecting incoming connection from %u.%u.%u.%u (expecting %u.%u.%u.%u)\n",
                           accept_ip[0], accept_ip[1], accept_ip[2], accept_ip[3],
                           listen_ip[0], listen_ip[1], listen_ip[2], listen_ip[3]);
                DNBLogThreaded ("error: rejecting connection from %u.%u.%u.%u (expecting %u.%u.%u.%u)",
                                accept_ip[0], accept_ip[1], accept_ip[2], accept_ip[3],
                                listen_ip[0], listen_ip[1], listen_ip[2], listen_ip[3]);
            }
        }
    }

    ClosePort (listen_fd, false);

    if (err.Fail())
    {
        return rnb_err;
    }
    else
    {
        // Keep our TCP packets coming without any delays.
        SetSocketOption (m_fd, IPPROTO_TCP, TCP_NODELAY, 1);
    }

    return rnb_success;
}