diff options
-rw-r--r-- | synapse_topology/controller/server/schemas.py | 6 | ||||
-rw-r--r-- | synapse_topology/controller/server/server.py | 13 | ||||
-rw-r--r-- | synapse_topology/controller/server/utils.py | 17 |
3 files changed, 36 insertions, 0 deletions
diff --git a/synapse_topology/controller/server/schemas.py b/synapse_topology/controller/server/schemas.py index 8420ef62eb..f3774777b2 100644 --- a/synapse_topology/controller/server/schemas.py +++ b/synapse_topology/controller/server/schemas.py @@ -33,3 +33,9 @@ CERTS_SCHEMA = { }, "required": ["cert", "cert_key"], } + +PORTS_SCHEMA = { + "type": "object", + "properties": {"ports": {"type": "array"}}, + "required": ["ports"], +} diff --git a/synapse_topology/controller/server/server.py b/synapse_topology/controller/server/server.py index bb8af0c553..713bec9714 100644 --- a/synapse_topology/controller/server/server.py +++ b/synapse_topology/controller/server/server.py @@ -5,12 +5,15 @@ from synapse_topology import model from twisted.web.static import File +from .utils import port_checker + from . import error_handlers from .schemas import ( BASE_CONFIG_SCHEMA, SERVERNAME_SCHEMA, CERT_PATHS_SCHEMA, CERTS_SCHEMA, + PORTS_SCHEMA, ) from .utils import validate_schema @@ -85,3 +88,13 @@ def test_cert_paths(request, body): @validate_schema(CERTS_SCHEMA) def upload_certs(request, body): model.add_certs(**body) + + +@app.route("/ports", methods=["POST"]) +@validate_schema(PORTS_SCHEMA) +def check_ports(request, body): + results = [] + for port in body["ports"]: + results.append(port_checker(port)) + return json.dumps({"ports": results}) + diff --git a/synapse_topology/controller/server/utils.py b/synapse_topology/controller/server/utils.py index 009a1a1c79..3d7134a43a 100644 --- a/synapse_topology/controller/server/utils.py +++ b/synapse_topology/controller/server/utils.py @@ -3,6 +3,9 @@ from functools import wraps from canonicaljson import json from jsonschema import validate +from contextlib import closing +import socket + def validate_schema(schema): def _wrap_validate(func): @@ -15,3 +18,17 @@ def validate_schema(schema): return _do_validate return _wrap_validate + + +def port_checker(port): + if port < 0 or 65535 < port: + return False + + with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as sock: + try: + sock.bind((socket.gethostname(), port)) + sock.listen() + sock.close() + return True + except: + return False |