Exemple #1
0
 def resolve(self, hostname, callback):
     if type(hostname) != bytes:
         hostname = hostname.encode('utf8')
     if not hostname:
         callback(None, Exception('empty hostname'))
     elif utils.is_ip(hostname):
         callback((hostname, hostname), None)
     elif hostname in self._hosts:
         logging.debug('hit hosts: %s', hostname)
         ip = self._hosts[hostname]
         callback((hostname, ip), None)
     elif hostname in self._cache:
         logging.debug('hit cache: %s', hostname)
         ip = self._cache[hostname]
         callback((hostname, ip), None)
     else:
         if not is_valid_hostname(hostname):
             callback(None, Exception('invalid hostname: %s' % hostname))
             return
         if hostname in self._cbs:  # if hostname is under-resolving, just adds cb to
             self.add_callback(
                 hostname,  # callback list, doesn't send new request any more.
                 callback)
             return
         try:
             self._send_req(
                 hostname,
                 DNSParser.QTYPE_A)  # ipv4 first. if failed, send ipv6 req
             self._hostname_status[hostname] = DNSParser.QTYPE_A
             self.add_callback(hostname, callback)
         except InvalidDomainName as e:
             logging.warn("invalid hostname when build dns request: %s" %
                          hostname)
Exemple #2
0
def http2shadosocks(data):
    """
    genearte http response and shadowsocks premble
    """
    words = data.split()
    if len(words) < 3:
        raise HttpRequestError(400, "Bad request version")
    method, path, version = words[:3]
    https = True if method.upper() == "CONNECT" else False
    if version[:5] != 'HTTP/':
        raise HttpRequestError(400, "Bad request version (%r)" % version)
    # socks5 request format
    cmd = 0x01  # connect
    try:
        if https:
            host, port = path.split(":")
        else:
            result = urlparse.urlsplit(path)
            host = result.hostname
            if not host:
                logging.debug(data)
                raise HttpRequestError(400, "Bad request")
            port = result.port or 80
            uri = result.path or "/"
            if result.query:
                data += (result.query + "\r\n")
    except IndexError:
        raise HttpRequestError(400, "Bad request")
    atyp = utils.is_ip(host)
    if not atyp:
        atyp = struct.pack("!B", 0x03)
        addr = struct.pack("!B", len(host)) + \
            utils.to_bytes(host)
    elif atyp == socket.AF_INET:
        addr = utils.inet_pton(atyp, host)
        atyp = struct.pack("!B", 0x01)
    else:
        addr = utils.inet_pton(atyp, host)
        atyp = struct.pack("!B", 0x04)
    premble = atyp + addr + struct.pack("!H", int(port))
    if not https:
        premble += data.replace(path, uri, 1)
    addr = (utils.to_str(host), port)
    http_response = "%s 200 Connection Established\r\n"\
    "Proxy-Agent: myss\r\n"\
    "\r\n" % version if https else ""
    return http_response, premble, addr
Exemple #3
0
 def _parse_hosts(self):
     etc_path = '/etc/hosts'
     if 'WINDIR' in os.environ:
         etc_path = os.environ['WINDIR'] + '/system32/drivers/etc/hosts'
     try:
         with open(etc_path, 'rb') as f:
             for line in f.readlines():
                 line = line.strip()
                 parts = line.split()
                 if len(parts) >= 2:
                     ip = parts[0]
                     if utils.is_ip(ip):
                         for i in range(1, len(parts)):
                             hostname = parts[i]
                             if hostname:
                                 self._hosts[hostname] = ip
     except IOError:
         self._hosts['localhost'] = '127.0.0.1'
Exemple #4
0
 def _parse_resolv(self):
     self._servers = []
     try:
         with open('/etc/resolv.conf', 'rb') as f:
             content = f.readlines()
             for line in content:
                 line = line.strip()
                 if line:
                     if line.startswith(b'nameserver'):
                         parts = line.split()
                         if len(parts) >= 2:
                             server = parts[1]
                             if utils.is_ip(server) == socket.AF_INET:
                                 if type(server) != str:
                                     server = server.decode('utf8')
                                 self._servers.append(server)
     except IOError:
         pass
     if not self._servers:
         self._servers = ['8.8.4.4', '8.8.8.8']