UDP守护程序的systemd-activate套接字激活

时间:2015-12-25 06:18:04

标签: sockets datagram systemd

我喜欢在开发过程中使用systemd-activate(8) 测试套接字激活的守护进程, 但是,它似乎只侦听TCP连接:

% /usr/lib/systemd/systemd-activate -l 5700 ./prog
Listening on [::]:5700 as 3.

% netstat -nl |grep 5700
tcp6       0      0 :::5700             :::*             LISTEN 

我正在使用处理数据报(UDP)的程序。如何让systemd-activate监听UDP端口?还是有一个 使用其他工具执行此操作的简单方法,而不会遇到制作和安装systemd单元文件的麻烦?

3 个答案:

答案 0 :(得分:1)

最近已添加到systemd-activatehttps://github.com/systemd/systemd/pull/2411,并且在发布时将成为systemd-229的一部分。

答案 1 :(得分:0)

我不确定是否有办法systemd-activate

您可能希望使用一些.service单元文件和一个带有依赖项的.socket单元文件。在.socket单元中,您将描述ListenDatagram=选项。有关详细信息,请参阅here

答案 2 :(得分:0)

我最终写了一个简单的C程序来做这件事;下面的代码(公共领域)。

用法是:

./a.out <port-number> <prog> [<arg1> ...]

程序在<port-number>上打开一个UDP套接字,设置系统套接字激活的守护进程所期望的环境变量,然后用随后的参数执行<prog>

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>

int main(int argc, char **argv) {
    if (argc < 2) {
        printf("no port specified\n");
        return -1;
    }
    if (argc < 3) {
        printf("no program specified\n");
        return -1;
    }

    uint16_t port = htons((uint16_t) strtoul(argv[1], NULL, 10));
    if (port == 0 || errno) {
        printf("failed to parse port: %s\n", argv[1]);
        return -1;
    }

    /* create datagram socket */
    int fd = socket(AF_INET, SOCK_DGRAM, 0);
    if (fd < 0) {
        printf("failed to open socket; errno: %d\n", errno);
        return -1;
    }

    struct sockaddr_in sa;
    sa.sin_family = AF_INET;
    sa.sin_port = port;
    sa.sin_addr.s_addr = INADDR_ANY;

    /* bind socket to port */
    int r = bind(fd, (struct sockaddr *) &sa, sizeof(struct sockaddr_in));
    if (r < 0) {
        printf("bind failed; errno: %d\n", errno);
        return -1;
    }

    /* execute subprocess */
    setenv("LISTEN_FDS", "1", 0);
    execvp(argv[2], argv + 2);
}