From 7737b64e5ed833bcd562ae4a9f32a9a7f0431de0 Mon Sep 17 00:00:00 2001 From: Bence Szigeti Date: Tue, 29 Jul 2025 13:07:58 +0200 Subject: [PATCH] Add UDS support --- opensips/mi/__main__.py | 17 +++++++++++++---- opensips/mi/datagram.py | 35 +++++++++++++++++++++++------------ opensips/version.py | 2 +- 3 files changed, 37 insertions(+), 17 deletions(-) diff --git a/opensips/mi/__main__.py b/opensips/mi/__main__.py index 755d96e..757662a 100644 --- a/opensips/mi/__main__.py +++ b/opensips/mi/__main__.py @@ -67,6 +67,10 @@ def load_env_file(env_file_path): metavar='FIFO_DIR', type=str, help='OpenSIPS MI FIFO Reply Directory') +communication.add_argument('-ds', '--datagram-socket', + metavar='SOCK', + type=str, + help='OpenSIPS Datagram Socket') group = parser.add_mutually_exclusive_group(required=True) @@ -128,10 +132,15 @@ def main(): elif args.type == 'http': mi = OpenSIPSMI('http', url=f'http://{args.ip}:{args.port}/mi') elif args.type == 'datagram': - mi = OpenSIPSMI('datagram', - datagram_ip=args.ip, - datagram_port=args.port, - timeout=0.1) + if args.datagram_socket: + mi = OpenSIPSMI('datagram', + datagram_unix_socket=args.datagram_socket, + timeout=0.1) + else: + mi = OpenSIPSMI('datagram', + datagram_ip=args.ip, + datagram_port=args.port, + timeout=0.1) else: if not args.bash_complete: print(f'Unknown type: {args.type}') diff --git a/opensips/mi/datagram.py b/opensips/mi/datagram.py index 59f7446..ff66438 100644 --- a/opensips/mi/datagram.py +++ b/opensips/mi/datagram.py @@ -20,37 +20,48 @@ """ MI Datagram implementation """ import socket +import os +from tempfile import NamedTemporaryFile from .connection import Connection from . import jsonrpc_helper - class Datagram(Connection): - """ MI Datagram connection """ def __init__(self, **kwargs): - if "datagram_ip" not in kwargs: - raise ValueError("datagram_ip is required for Datagram") + if "datagram_unix_socket" in kwargs: + self.address = kwargs["datagram_unix_socket"] + self.family = socket.AF_UNIX + self.recv_size = 65535 * 32 + with NamedTemporaryFile(prefix="opensips_mi_reply_", dir="/tmp") as nt: + self.recv_sock = nt.name + elif "datagram_ip" in kwargs and "datagram_port" in kwargs: + self.address = (kwargs["datagram_ip"], int(kwargs["datagram_port"])) + self.family = socket.AF_INET + self.recv_size = 32768 + self.recv_sock = None + else: + raise ValueError("Either datagram_unix_socket or both datagram_ip and datagram_port are required for Datagram") - if "datagram_port" not in kwargs: - raise ValueError("datagram_port is required for Datagram") - self.timeout = kwargs.get("timeout", 1) - self.ip = kwargs["datagram_ip"] - self.port = int(kwargs["datagram_port"]) def execute(self, method: str, params: dict): jsoncmd = jsonrpc_helper.get_command(method, params) - udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + udp_socket = socket.socket(self.family, socket.SOCK_DGRAM) try: - udp_socket.sendto(jsoncmd.encode(), (self.ip, self.port)) + if self.recv_sock: + udp_socket.bind(self.recv_sock) + udp_socket.sendto(jsoncmd.encode(), self.address) udp_socket.settimeout(self.timeout) - reply = udp_socket.recv(32768) + reply = udp_socket.recv(self.recv_size) except Exception as e: raise jsonrpc_helper.JSONRPCException(e) finally: + if self.recv_sock: + os.unlink(self.recv_sock) udp_socket.close() + return jsonrpc_helper.get_reply(reply) def valid(self): diff --git a/opensips/version.py b/opensips/version.py index 184b43b..d003d06 100644 --- a/opensips/version.py +++ b/opensips/version.py @@ -19,4 +19,4 @@ """ OpenSIPS Package version """ -__version__ = '0.1.5' +__version__ = '0.1.6'