def test_empty_defaults(self): self.assertEqual(parse_addr_spec("192.168.0.2:8888"), ("192.168.0.2", 8888)) self.assertEqual(parse_addr_spec("", defhost="", defport=0), ("", 0)) self.assertEqual(parse_addr_spec(":8888", defhost=""), ("", 8888)) self.assertRaises(ValueError, parse_addr_spec, ":8888") self.assertEqual(parse_addr_spec("192.168.0.2", defport=0), ("192.168.0.2", 0)) self.assertRaises(ValueError, parse_addr_spec, "192.168.0.2")
def get_reg(facilitator_addr, proxy_addr, proxy_transport_list): """ Get a client registration for proxy proxy_addr from the facilitator at facilitator_addr using a one-time socket. proxy_transport_list is a list containing the transport names that the flashproxy supports. Returns a dict with keys "client", "client-transport", "relay", and "relay-transport" if successful, or a dict with the key "client" mapped to the value "" if there are no registrations available for proxy_addr. Raises an exception otherwise.""" f = fac_socket(facilitator_addr) # Form a list (in transact() format) with the transports that we # should send to the facilitator. Then pass that list to the # transact() function. # For example, PROXY-TRANSPORT=obfs2 PROXY-TRANSPORT=obfs3. transports = [("PROXY-TRANSPORT", tp) for tp in proxy_transport_list] try: command, params = transact(f, "GET", ("FROM", format_addr(proxy_addr)), *transports) finally: f.close() response = {} check_back_in = param_first("CHECK-BACK-IN", params) if check_back_in is not None: try: float(check_back_in) except ValueError: raise ValueError( "Facilitator returned non-numeric polling interval.") response["check-back-in"] = check_back_in if command == "NONE": response["client"] = "" return response elif command == "OK": client_spec = param_first("CLIENT", params) client_transport = param_first("CLIENT-TRANSPORT", params) relay_spec = param_first("RELAY", params) relay_transport = param_first("RELAY-TRANSPORT", params) if not client_spec: raise ValueError("Facilitator did not return CLIENT") if not client_transport: raise ValueError("Facilitator did not return CLIENT-TRANSPORT") if not relay_spec: raise ValueError("Facilitator did not return RELAY") if not relay_transport: raise ValueError("Facilitator did not return RELAY-TRANSPORT") # Check the syntax returned by the facilitator. client = parse_addr_spec(client_spec) relay = parse_addr_spec(relay_spec) response["client"] = format_addr(client) response["client-transport"] = client_transport response["relay"] = format_addr(relay) response["relay-transport"] = relay_transport return response else: raise ValueError("Facilitator response was not \"OK\"")
def get_reg(facilitator_addr, proxy_addr, proxy_transport_list): """ Get a client registration for proxy proxy_addr from the facilitator at facilitator_addr using a one-time socket. proxy_transport_list is a list containing the transport names that the flashproxy supports. Returns a dict with keys "client", "client-transport", "relay", and "relay-transport" if successful, or a dict with the key "client" mapped to the value "" if there are no registrations available for proxy_addr. Raises an exception otherwise.""" f = fac_socket(facilitator_addr) # Form a list (in transact() format) with the transports that we # should send to the facilitator. Then pass that list to the # transact() function. # For example, PROXY-TRANSPORT=obfs2 PROXY-TRANSPORT=obfs3. transports = [("PROXY-TRANSPORT", tp) for tp in proxy_transport_list] try: command, params = transact(f, "GET", ("FROM", format_addr(proxy_addr)), *transports) finally: f.close() response = {} check_back_in = param_first("CHECK-BACK-IN", params) if check_back_in is not None: try: float(check_back_in) except ValueError: raise ValueError("Facilitator returned non-numeric polling interval.") response["check-back-in"] = check_back_in if command == "NONE": response["client"] = "" return response elif command == "OK": client_spec = param_first("CLIENT", params) client_transport = param_first("CLIENT-TRANSPORT", params) relay_spec = param_first("RELAY", params) relay_transport = param_first("RELAY-TRANSPORT", params) if not client_spec: raise ValueError("Facilitator did not return CLIENT") if not client_transport: raise ValueError("Facilitator did not return CLIENT-TRANSPORT") if not relay_spec: raise ValueError("Facilitator did not return RELAY") if not relay_transport: raise ValueError("Facilitator did not return RELAY-TRANSPORT") # Check the syntax returned by the facilitator. client = parse_addr_spec(client_spec) relay = parse_addr_spec(relay_spec) response["client"] = format_addr(client) response["client-transport"] = client_transport response["relay"] = format_addr(relay) response["relay-transport"] = relay_transport return response else: raise ValueError("Facilitator response was not \"OK\"")
def read_client_registrations(body, defhost=None, defport=None): """Yield client registrations (as Endpoints) from an encoded registration message body. The message format is one registration per line, with each line being encoded as application/x-www-form-urlencoded. The key "client" is required and contains the client address and port (perhaps filled in by defhost and defport). The key "client-transport" is optional and defaults to "websocket". Example: client=1.2.3.4:9000&client-transport=websocket client=1.2.3.4:9090&client-transport=obfs3|websocket """ for line in body.splitlines(): qs = urlparse.parse_qs(line, keep_blank_values=True, strict_parsing=True) # Get the unique value associated with the given key in qs. If the key # is absent or appears more than once, raise ValueError. def get_unique(key, default=None): try: vals = qs[key] except KeyError: if default is None: raise ValueError("missing %r key" % key) vals = (default, ) if len(vals) != 1: raise ValueError("more than one %r key" % key) return vals[0] addr = parse_addr_spec(get_unique("client"), defhost, defport) transport = get_unique("client-transport", DEFAULT_CLIENT_TRANSPORT) yield reg.Endpoint(addr, transport)
def read_client_registrations(body, defhost=None, defport=None): """Yield client registrations (as Endpoints) from an encoded registration message body. The message format is one registration per line, with each line being encoded as application/x-www-form-urlencoded. The key "client" is required and contains the client address and port (perhaps filled in by defhost and defport). The key "client-transport" is optional and defaults to "websocket". Example: client=1.2.3.4:9000&client-transport=websocket client=1.2.3.4:9090&client-transport=obfs3|websocket """ for line in body.splitlines(): qs = urlparse.parse_qs(line, keep_blank_values=True, strict_parsing=True) # Get the unique value associated with the given key in qs. If the key # is absent or appears more than once, raise ValueError. def get_unique(key, default=None): try: vals = qs[key] except KeyError: if default is None: raise ValueError("missing %r key" % key) vals = (default,) if len(vals) != 1: raise ValueError("more than one %r key" % key) return vals[0] addr = parse_addr_spec(get_unique("client"), defhost, defport) transport = get_unique("client-transport", DEFAULT_CLIENT_TRANSPORT) yield reg.Endpoint(addr, transport)
def add_registration_args(parser): add_module_opts(parser) parser.add_argument("remote_addr", metavar="ADDR:PORT", help="external addr+port to register, default %s" % format_addr(DEFAULT_REMOTE), default="", nargs="?", type=lambda x: parse_addr_spec(x, *DEFAULT_REMOTE))
def test_defhost_defport_ipv6(self): self.assertEqual(parse_addr_spec("[1234::2]:8888", defhost="1234::1", defport=9999), ("1234::2", 8888)) self.assertEqual(parse_addr_spec("[1234::2]:", defhost="1234::1", defport=9999), ("1234::2", 9999)) self.assertEqual(parse_addr_spec("[1234::2]", defhost="1234::1", defport=9999), ("1234::2", 9999)) self.assertEqual(parse_addr_spec(":8888", defhost="1234::1", defport=9999), ("1234::1", 8888)) self.assertEqual(parse_addr_spec(":", defhost="1234::1", defport=9999), ("1234::1", 9999)) self.assertEqual(parse_addr_spec("", defhost="1234::1", defport=9999), ("1234::1", 9999))
def test_defhost_defport_ipv4(self): self.assertEqual(parse_addr_spec("192.168.0.2:8888", defhost="192.168.0.1", defport=9999), ("192.168.0.2", 8888)) self.assertEqual(parse_addr_spec("192.168.0.2:", defhost="192.168.0.1", defport=9999), ("192.168.0.2", 9999)) self.assertEqual(parse_addr_spec("192.168.0.2", defhost="192.168.0.1", defport=9999), ("192.168.0.2", 9999)) self.assertEqual(parse_addr_spec(":8888", defhost="192.168.0.1", defport=9999), ("192.168.0.1", 8888)) self.assertEqual(parse_addr_spec(":", defhost="192.168.0.1", defport=9999), ("192.168.0.1", 9999)) self.assertEqual(parse_addr_spec("", defhost="192.168.0.1", defport=9999), ("192.168.0.1", 9999))
def parse(cls, spec, transport, defhost = None, defport = None): host, port = parse_addr_spec(spec, defhost, defport) return cls((host, port), Transport.parse(transport))
def test_ipv4(self): self.assertEqual(parse_addr_spec("192.168.0.1:9999"), ("192.168.0.1", 9999))
def test_canonical_ip_noresolve(self): """Test that canonical_ip does not do DNS resolution by default.""" self.assertRaises(ValueError, canonical_ip, *parse_addr_spec("example.com:80"))
def test_ipv6(self): self.assertEqual(parse_addr_spec("[12::34]:9999"), ("12::34", 9999))
def parse(cls, spec, transport, defhost=None, defport=None): host, port = parse_addr_spec(spec, defhost, defport) return cls((host, port), Transport.parse(transport))