Re: [systemd-devel] How to get a useful peer address when doing accept(3, ...) on a systemd supplied listening socket

2022-10-27 Thread Klaus Ebbe Grue
Hi Mantas


> I have a feeling it "changes" because you're trying to give the whole
> struct sockaddr to inet_pton() instead of giving just the .sin6_addr field,
> so your program is trying to interpret the *port number*
> (i.e. the .sin6_port which precedes .sin_addr) as part of the address...

That was exactly my mistake! Thanks.

At some point in my hopeless odyssey down a wrong track I tried giving the 
whole struct to inet_ntop() and forgot to change it back when I got everything 
else to work.

Thanks for your help and sorry for the inconvenience.

Cheers,
Klaus



[systemd-devel] How to get a useful peer address when doing accept(3, ...) on a systemd supplied listening socket

2022-10-27 Thread Klaus Ebbe Grue
Hi systemd-devel,

Sorry to bug you with another user question.

I have a socket activated daemon, call it mydaemon, and I have trouble finding 
out who connects to it.


mydaemon.socket contains:


  [Socket]
  ListenStream=

When I connect using IPv4 using

  nc -4 localhost 

then mydaemon does

  sockaddr_in6 peer;
  socklen_t peer_size=sizeof(peer);
  accept(3,(struct sockaddr *),sizeof(peer))


Afterwards, peer.sin6_family is AF_INET6 and peer.sin6_addr contains some 
gibberish like a00:e5ae::


If I connect more than once, the gibberish changes from connection to 
connection.


Something similar happens if I connect using IPv6.


If I change mydaemon.socket to


  [Socket]
  ListenStream=0.0.0.0:

Then peer.sin6_family becomes AF_INET as it should. But if peer is cast to 
struct sockaddr_in then peer.sin_addr still contains gibberish like 2.0.191.150 
(I expected something like 127.0.0.1 or 192.168.0.99).

When I connect from other machines, the peer address still is gibberish.

If mydaemon creates the listening socket, I can easily get the peer address.

I suspect that when systemd creates the listening socket then accept(3,...) 
returns a socket which is connected to a local socket created by systemd.

QUESTION: Is that suspicion correct? And if yes, is there are way to recover 
the address of the actually connecting peer?

Cheers,
Klaus



Re: [systemd-devel] Is it possible to let systemd create a listening socket and yet be able to have that socket activate nothing, at least temporarily?

2022-10-11 Thread Klaus Ebbe Grue
Hi Lennart,

> Can't you run your upgrade script in idempotent way as a helper
> service that is pulled in by your main daemon and ordered before it,
> but conditions itself out if it already did its job? that's usually
> the most robust way, since then it's sufficient to just restart your
> daemon or reboot, and everything will always catch up correctly.

> i.e. if you have foo-daemon.socket + foo-daemon.service then define
> foo-upgrade.service that is pulled in from foo-daemon.service via
> `Wants=foo-upgrade.service` + `After=foo-upgrade.service`. And then
> add `ConditionFileExists=!/some/touch/file` to `foo-upgrade.service` to
> make it a NOP if things have already been updated, using a touch
> file. (some better, smarter condition check might work as well, see
> man pages of things systemd can check for you).

That is a great pattern!

A Type=oneshot seems useful for the upgrade process.

For the record, I have appended what ended up working.

Thanks!

Cheers,
Klaus

---

The following three unit files open a listening socket, run the myupgrade 
service,
and only then start the /usr/bin/mydaemon service. The socket listens while the
myupgrade service runs so that clients can connect. But the clients are queued
until myupgrade has finished and /usr/bin/mydaemon starts accepting
connections.

mydeamon.service:
[Unit]
Description=service that does something
After=mydaemon.socket
Requires=mydaemon.socket
After=myupgrade.service
Wants=myupgrade.service
[Install]
WantedBy=multi-user.target
[Service]
Type=simple
ExecStart=/usr/bin/mydaemon

myupgrade.service:
[Unit]
Description=service to run before mydaemon
[Service]
Type=oneshot
ExecStart=/usr/bin/bash -c "echo goodnight;sleep 60;echo goodmorning"

mydeamon.socket
[Unit]
Description=mydaemon listen socket
[Socket]
ListenStream=
[Install]
WantedBy=sockets.target



Re: [systemd-devel] Is it possible to let systemd create a listening socket and yet be able to have that socket activate nothing, at least temporarily?

2022-10-07 Thread Klaus Ebbe Grue
Hi Mantas,


Thanks for the suggestion. I will take a look at it.  When i do not want to do

  int flag=1;
  int rv=setsockopt(listen_fd,SOL_SOCKET,SO_REUSEADDR,,sizeof(flag));
the central problem will be to avoid the 1 minute delay

Cheers,
Klaus



Fra: Mantas Mikulėnas 
Sendt: 7. oktober 2022 09:51
Til: Klaus Ebbe Grue
Cc: systemd-devel@lists.freedesktop.org
Emne: Re: [systemd-devel] Is it possible to let systemd create a listening 
socket and yet be able to have that socket activate nothing, at least 
temporarily?


You don't often get email from graw...@gmail.com. Learn why this is 
important<https://aka.ms/LearnAboutSenderIdentification>

On Fri, Oct 7, 2022 at 10:24 AM Klaus Ebbe Grue 
mailto:g...@di.ku.dk>> wrote:

Hi systemd-devel,

I have a user question which I take the liberty to send here since "about 
systemd-devel" says "... it's also OK to direct user questions to this mailing 
list ...".

I have a daemon, /usr/bin/mydaemon, which listens on one and only one TCP port, 
say , and which does no more than communicating over  and creating, 
reading, writing and deleting files in /home/me/mydaemon/.

Mydaemon leaves it to systemd to create a socket which listens at .

It is unimportant whether or not mydaemon is started at boot and it is also 
unimportant whether or not mydaemon is socket activated. As long as it is at 
least one of the two.

Now I want to upgrade mydaemon to a new version using a script, without race 
conditions and without closing the listening socket. I want the listening 
socket to stay open since otherwise there can be a one minute interval during 
which it is impossible to reopen .

If it is just a clean upgrade, the script could replace /usr/bin/mydaemon, then 
stop mydaemon. If the daemon is socket activated there is no more to do. If the 
daemon is activated only on boot then the script must end up restarting 
mydaemon.

But now I want to do some more while mydaemon is not running. It could be that 
my script should take a backup of /home/me/mydaemon/ in case things go wrong. 
It could be the script should translate some file in /home/me/mydaemon/ to some 
new format required by the new mydaemon or whatever.

So I need to stop mydaemon in such a way that mydaemon cannot wake up while my 
script fiddles with /home/me/mydaemon/.

Deploy the new version of your daemon to another location 
(/home/me/mydaemon.new/), perform all processing/conversions that are 
necessary, *then* stop the socket, `mv mydaemon mydaemon.old`, stop the 
service, `mv mydaemon.new mydaemon`, start the socket again. The interval for 
this will be more like half a second than a minute.

--
Mantas Mikulėnas


Re: [systemd-devel] Is it possible to let systemd create a listening socket and yet be able to have that socket activate nothing, at least temporarily?

2022-10-07 Thread Klaus Ebbe Grue
Hi Michael,


> Unfortunately not. You'd need some kind of "maintenance" mode ...

Thanks a lot. I will go with the maintenance mode without fearing to have 
missed some systemd feature.

Cheers,
Klaus



[systemd-devel] Is it possible to let systemd create a listening socket and yet be able to have that socket activate nothing, at least temporarily?

2022-10-07 Thread Klaus Ebbe Grue
Hi systemd-devel,

I have a user question which I take the liberty to send here since "about 
systemd-devel" says "... it's also OK to direct user questions to this mailing 
list ...".

I have a daemon, /usr/bin/mydaemon, which listens on one and only one TCP port, 
say , and which does no more than communicating over  and creating, 
reading, writing and deleting files in /home/me/mydaemon/.

Mydaemon leaves it to systemd to create a socket which listens at .

It is unimportant whether or not mydaemon is started at boot and it is also 
unimportant whether or not mydaemon is socket activated. As long as it is at 
least one of the two.

Now I want to upgrade mydaemon to a new version using a script, without race 
conditions and without closing the listening socket. I want the listening 
socket to stay open since otherwise there can be a one minute interval during 
which it is impossible to reopen .

If it is just a clean upgrade, the script could replace /usr/bin/mydaemon, then 
stop mydaemon. If the daemon is socket activated there is no more to do. If the 
daemon is activated only on boot then the script must end up restarting 
mydaemon.

But now I want to do some more while mydaemon is not running. It could be that 
my script should take a backup of /home/me/mydaemon/ in case things go wrong. 
It could be the script should translate some file in /home/me/mydaemon/ to some 
new format required by the new mydaemon or whatever.

So I need to stop mydaemon in such a way that mydaemon cannot wake up while my 
script fiddles with /home/me/mydaemon/.

According to https://0pointer.de/blog/projects/three-levels-of-off it seems 
that that was possible in 2011: just do "systemctl disable mydaemon.service". 
But when I try that, mydaemon still wakes up if I connect to  using eg 
netcat.

I have also tried to mask mydaemon. But if I then connect to  using netcat, 
then netcat gets kicked of. And if I try again then  is no longer listening.

QUESTION: Is it possible to let systemd create a listening socket and yet be 
able to have that socket activate nothing, at least temporarily?

Cheers,
Klaus