示例#1
0
文件: dns.cpp 项目: RankoR/mqutim
  DNS::HostMap DNS::resolve( const std::string& service, const std::string& proto,
                             const std::string& domain, const LogSink& logInstance )
  {
    const std::string dname = "_" +  service + "._" + proto + "." + domain;
    bool error = false;

    DNS::HostMap servers;
    DNS_RECORD* pRecord;
    if( DnsQuery( dname.c_str(), DNS_TYPE_SRV, DNS_QUERY_STANDARD, NULL, &pRecord, NULL ) == ERROR_SUCCESS )
    {
      DNS_RECORD* pRec = pRecord;
      do
      {
        if( pRec->wType == DNS_TYPE_SRV )
        {
          servers[pRec->Data.SRV.pNameTarget] = pRec->Data.SRV.wPort;
        }
        pRec = pRec->pNext;
      }
      while( pRec != NULL );
      DnsRecordListFree( pRecord, DnsFreeRecordList );
    }
    else
      error = true;

    if( error || !servers.size() )
    {
      servers = defaultHostMap( domain, logInstance );
    }

    return servers;
  }
  void ConnectionSOCKS5Proxy::handleConnect( const ConnectionBase* /*connection*/ )
  {
    if( m_connection )
    {
      std::string server = m_server;
      int port = m_port;
      if( port == -1 )
      {
        DNS::HostMap servers = DNS::resolve( m_server, m_logInstance );
        if( servers.size() )
        {
          server = (*(servers.begin())).first;
          port = (*(servers.begin())).second;
        }
      }
      m_logInstance.log( LogLevelDebug, LogAreaClassConnectionSOCKS5Proxy,
                         "attempting to negotiate socks5 proxy connection" );

      bool auth = !m_proxyUser.empty() && !m_proxyPassword.empty();
      char *d = new char[auth ? 4 : 3];
      d[0] = 0x05; // SOCKS version 5
      if( auth )
      {
        d[1] = 0x02; // two methods
        d[3] = 0x02; // method: username/password auth
      }
      else
        d[1] = 0x01; // one method
      d[2] = 0x00; // method: no auth

      if( !send( std::string( d, auth ? 4 : 3 ) ) )
      {
        cleanup();
        if( m_handler )
          m_handler->handleDisconnect( this, ConnIoError );
      }
      delete[] d;
    }
  }
示例#3
0
  DNS::HostMap DNS::resolve( const std::string& service, const std::string& proto,
                             const std::string& domain, const LogSink& logInstance )
  {
    const std::string dname = "_" +  service + "._" + proto + "." + domain;
    bool error = false;

    DNS::HostMap servers;
    DNS_RECORD* pRecord = NULL;
    DNS_STATUS status = DnsQuery_UTF8( dname.c_str(), DNS_TYPE_SRV, DNS_QUERY_STANDARD, NULL, &pRecord, NULL );
    if( status == ERROR_SUCCESS )
    {
      // NOTE: DnsQuery_UTF8 and DnsQuery_A really should have been defined with
      // PDNS_RECORDA instead of PDNS_RECORD, since that's what it is (even with _UNICODE defined).
      // We'll correct for that mistake with a cast.
      DNS_RECORDA* pRec = (DNS_RECORDA*)pRecord;
      do
      {
        if( pRec->wType == DNS_TYPE_SRV )
        {
          servers[pRec->Data.SRV.pNameTarget] = pRec->Data.SRV.wPort;
        }
        pRec = pRec->pNext;
      }
      while( pRec != NULL );
      DnsRecordListFree( pRecord, DnsFreeRecordList );
    }
    else
    {
      logInstance.warn( LogAreaClassDns, "DnsQuery_UTF8() failed: " + util::int2string( status ) );
      error = true;
    }

    if( error || !servers.size() )
    {
      servers = defaultHostMap( domain, logInstance );
    }

    return servers;
  }
  void ConnectionSOCKS5Proxy::negotiate()
  {
    m_s5state = S5StateNegotiating;
    char *d = new char[m_ip ? 10 : 6 + m_server.length() + 1];
    int pos = 0;
    d[pos++] = 0x05; // SOCKS version 5
    d[pos++] = 0x01; // command CONNECT
    d[pos++] = 0x00; // reserved
    int port = m_port;
    std::string server = m_server;
    if( m_ip ) // IP address
    {
      d[pos++] = 0x01; // IPv4 address
      std::string s;
      int j = server.length();
      int l = 0;
      for( int k = 0; k < j && l < 4; ++k )
      {
        if( server[k] != '.' )
          s += server[k];

        if( server[k] == '.' || k == j-1 )
        {
          d[pos++] = atoi( s.c_str() ) & 0x0FF;
          s = "";
          ++l;
        }
      }
    }
    else // hostname
    {
      if( port == -1 )
      {
        DNS::HostMap servers = DNS::resolve( m_server, m_logInstance );
        if( servers.size() )
        {
          server = (*(servers.begin())).first;
          port = (*(servers.begin())).second;
        }
      }
      d[pos++] = 0x03; // hostname
      d[pos++] = m_server.length();
      strncpy( d + pos, m_server.c_str(), m_server.length() );
      pos += m_server.length();
    }
    int nport = htons( port );
    d[pos++] = nport;
    d[pos++] = nport >> 8;

#ifndef _WIN32_WCE
    std::ostringstream oss;
    oss << "requesting socks5 proxy connection to " << server << ":" << port;
    m_logInstance.log( LogLevelDebug, LogAreaClassConnectionSOCKS5Proxy, oss.str() );
#endif

    if( !send( std::string( d, pos ) ) )
    {
      cleanup();
      m_handler->handleDisconnect( this, ConnIoError );
    }
    delete[] d;
  }