0

I am working on RedHat7.5.

I made a systemd socket (/etc/systemd/system/barfoo.socket):

[Unit]
Description=This is the barfoo socket

[Socket]
ListenStream=0.0.0.0:123
NoDelay=true
BindIPv6Only=both

For learners: BindIPv6Only=both opens the port for IPv6 and IPv4. The format ListenStream=0.0.0.0:123 opens the port explicitly for IPv4.

and a corresponding systemd service (/etc/systemd/system/barfoo.service):

For learners: It is important that the service file and the socket file have the same name

[Unit]
Description=This is the barfoo service
Requires=barfoo.socket

[Service]
RestartSec=2s
User=installation
Group=installation
ExecStart=/home/installation/tests/a.out
Restart=always

[Install]
WantedBy=multi-user.target

For learners: "Requires=barfoo.socket" makes the socket available to this service. RestartSec and Restart will make the service restarted every 2 seconds (after exit). User and Group make the service run with the privileges of installation. ExecStart is the actual binary to start.

I also made a small test program (test.c):

#include<stdio.h> 
#include<arpa/inet.h> 

int main() 
{ 
    int server = socket(AF_INET, SOCK_STREAM, 0); 
    if (server < 0) 
        printf("Error in server creating\n"); 
    else
        printf("Server Created\n"); 

    struct sockaddr_in my_addr, peer_addr; 
    my_addr.sin_family = AF_INET; 
    my_addr.sin_addr.s_addr = INADDR_ANY; 
    my_addr.sin_addr.s_addr = inet_addr("10.0.1.10"); 
    int b = 1, i = 123; 

    my_addr.sin_port = htons(i); 

    b = bind(server, (struct sockaddr*) &my_addr, sizeof(my_addr)); 

    if(b)
      printf("Error binding to port %d, return %d\n", i, b);
    else
      printf("Bound to port %d, return %d\n", i, b); 

   return 0;
}

Then I did:

  • gcc test.c (which creates a.out)
  • systemctl daemon-reload (which makes systemd read my barfoo files)
  • systemctl start barfoo

When I do netstat -tulpen I can see that systemd has opened the port. But the service (a.out) returns always "Error binding to port...".

The idea is to make the port 123 available to a program which is running with non-root privileges. Normally ports below 1024 are only available to root.

My Question is: Why is it not working/ What am I doing wrong?

1
  • If you are gonna active the socket, then systemd will open the socket with IPv4 -Tcp 0.0.0.0:123, which is a broadcast address, without any socket option, how can you be able to bind another 123 port? stackoverflow.com/questions/14388706/… So I feel strange about your code, please correct me if I'm wrong. – 炸鱼薯条德里克 Sep 14 '18 at 13:52
3

What am I doing wrong?

You haven't written any actual test program code.

Nearly every single line of code in your test program so far is unnecessary. systemd has opened the socket, bound it, and passed it as an open file descriptor to your program. None of that you do yourself.

At the moment that leaves return 0; as the single appropriate statement in your program.

You must decide whether your program is a listening or an accepting program. Listening programs receive an open file descriptor for a listening socket; accepting programs receive an open file descriptor for an accepted connection socket.

Further reading

0

Port 123 is the port for network time. Do you have the ntpd or chronyd service, or some other service that uses the Network Time Protocol (NTP) to synchronize time on the server?

For any custom services, it is recommended that you use ports not already defined in the /etc/services file.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.