diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | FLOW.md | 6 | ||||
-rw-r--r-- | Makefile | 27 | ||||
-rw-r--r-- | README.md | 47 | ||||
-rw-r--r-- | avahi/pacserve.service.in | 15 | ||||
-rw-r--r-- | config.def.h | 6 | ||||
-rw-r--r-- | initcpio/hooks/pacredir | 22 | ||||
-rw-r--r-- | initcpio/install/pacredir | 11 | ||||
-rwxr-xr-x | networkmanager/80-pacredir | 2 | ||||
-rw-r--r-- | pacredir.c | 38 | ||||
-rw-r--r-- | pacredir.h | 3 | ||||
-rw-r--r-- | pacserve.conf | 4 | ||||
-rw-r--r-- | systemd/pacredir.service | 4 | ||||
-rw-r--r-- | systemd/pacserve-announce.service.in | 23 | ||||
-rw-r--r-- | systemd/pacserve.service | 7 | ||||
-rw-r--r-- | systemd/sysusers.conf | 2 |
16 files changed, 122 insertions, 97 deletions
@@ -4,7 +4,7 @@ arch pacredir config.h -avahi/pacserve.service +systemd/pacserve-announce.service version.h pacredir-*.tar.xz pacredir-*.tar.xz.asc @@ -1,7 +1,7 @@ pacredir - request flow ======================= -[◀ Go back to main README](README.md) +[⬅️ Go back to main README](README.md) Whenever `pacman` sends a request to `pacredir` a number of requests (increasing with the number of hosts found) is sent through the network. @@ -34,5 +34,5 @@ All requests made by `pacredir` are answered with http code `404`, thus `pacman` receives the same. Finally `pacman` falls back to the next mirror. --- -[◀ Go back to main README](README.md) -[▲ Go back to top](#top) +[⬅️ Go back to main README](README.md) +[⬆️ Go back to top](#top) @@ -28,42 +28,41 @@ ID := $(shell shopt -u extglob && source /etc/os-release && echo $$ID) # this is just a fallback in case you do not use git but downloaded # a release tarball... -VERSION := 0.4.7 +VERSION := 0.6.0 MARKDOWN = $(wildcard *.md) HTML = $(MARKDOWN:.md=.html) -all: pacredir avahi/pacserve.service $(HTML) +all: pacredir systemd/pacserve-announce.service $(HTML) pacredir: pacredir.c pacredir.h config.h version.h - $(CC) pacredir.c $(CFLAGS) $(CFLAGS_EXTRA) $(LDFLAGS) -DREPRODUCIBLE=$(REPRODUCIBLE) -DARCH=\"$(ARCH)\" -DID=\"$(ID)\" -o pacredir + $(CC) $< $(CFLAGS) $(CFLAGS_EXTRA) $(LDFLAGS) -DREPRODUCIBLE=$(REPRODUCIBLE) -o $@ -config.h: - $(CP) config.def.h config.h +config.h: config.def.h + $(CP) $< $@ version.h: $(wildcard .git/HEAD .git/index .git/refs/tags/*) Makefile - printf "#ifndef VERSION\n#define VERSION \"%s\"\n#endif\n" $(shell git describe --long 2>/dev/null || echo ${VERSION}) > $@ + printf "#ifndef VERSION\n#define VERSION \"%s\"\n#endif\n#define ARCH \"%s\"\n#define ID \"%s\"\n" $(shell git describe --long 2>/dev/null || echo ${VERSION}) $(ARCH) $(ID) > $@ -avahi/pacserve.service: avahi/pacserve.service.in - $(SED) 's/%ARCH%/$(ARCH)/;s/%ID%/$(ID)/' avahi/pacserve.service.in > avahi/pacserve.service +systemd/pacserve-announce.service: systemd/pacserve-announce.service.in + $(SED) 's/%ARCH%/$(ARCH)/;s/%ID%/$(ID)/' $< > $@ %.html: %.md Makefile markdown $< | sed 's/href="\([-[:alnum:]]*\)\.md"/href="\1.html"/g' > $@ install: install-bin install-doc -install-bin: pacredir avahi/pacserve.service +install-bin: pacredir systemd/pacserve-announce.service $(INSTALL) -D -m0755 pacredir $(DESTDIR)$(PREFIX)/bin/pacredir $(LN) -s darkhttpd $(DESTDIR)$(PREFIX)/bin/pacserve $(INSTALL) -D -m0644 pacredir.conf $(DESTDIR)/etc/pacredir.conf + $(INSTALL) -D -m0644 pacserve.conf $(DESTDIR)/etc/pacserve.conf $(INSTALL) -D -m0644 pacman/pacredir $(DESTDIR)/etc/pacman.d/pacredir - $(INSTALL) -D -m0644 avahi/pacserve.service $(DESTDIR)/etc/avahi/services/pacserve.service $(INSTALL) -D -m0644 systemd/pacredir.service $(DESTDIR)$(PREFIX)/lib/systemd/system/pacredir.service $(INSTALL) -D -m0644 systemd/pacserve.service $(DESTDIR)$(PREFIX)/lib/systemd/system/pacserve.service + $(INSTALL) -D -m0644 systemd/pacserve-announce.service $(DESTDIR)$(PREFIX)/lib/systemd/system/pacserve-announce.service $(INSTALL) -D -m0644 systemd/sysusers.conf $(DESTDIR)$(PREFIX)/lib/sysusers.d/pacredir.conf $(INSTALL) -D -m0644 systemd/tmpfiles.conf $(DESTDIR)$(PREFIX)/lib/tmpfiles.d/pacredir.conf - $(INSTALL) -D -m0644 initcpio/hooks/pacredir $(DESTDIR)$(PREFIX)/lib/initcpio/hooks/pacredir - $(INSTALL) -D -m0644 initcpio/install/pacredir $(DESTDIR)$(PREFIX)/lib/initcpio/install/pacredir $(INSTALL) -D -m0644 dhcpcd/80-pacredir $(DESTDIR)$(PREFIX)/lib/dhcpcd/dhcpcd-hooks/80-pacredir $(INSTALL) -D -m0755 networkmanager/80-pacredir $(DESTDIR)$(PREFIX)/lib/NetworkManager/dispatcher.d/80-pacredir @@ -74,10 +73,10 @@ install-doc: $(HTML) $(INSTALL) -D -m0644 $(wildcard FLOW/*) -t $(DESTDIR)$(PREFIX)/share/doc/pacredir/FLOW/ clean: - $(RM) -f *.o *~ pacredir avahi/pacserve.service $(HTML) version.h + $(RM) -f *.o *~ pacredir systemd/pacserve-announce.service $(HTML) version.h distclean: - $(RM) -f *.o *~ pacredir avahi/pacserve.service $(HTML) version.h config.h + $(RM) -f *.o *~ pacredir systemd/pacserve-announce.service $(HTML) version.h config.h release: git archive --format=tar.xz --prefix=pacredir-$(VERSION)/ $(VERSION) > pacredir-$(VERSION).tar.xz @@ -1,29 +1,37 @@ pacredir ======== +[](https://github.com/eworm-de/pacredir/stargazers) +[](https://github.com/eworm-de/pacredir/network) +[](https://github.com/eworm-de/pacredir/watchers) + **pacredir - redirect pacman requests, assisted by avahi service discovery** -By default every [Arch Linux](https://www.archlinux.org/) installation +By default every [Arch Linux ↗️](https://www.archlinux.org/) installation downloads its package files from online mirrors, transferring all the bits via WAN connection. But often other Arch systems may be around that already have the files available on local storage - just a fast LAN connection away. This is -where `pacredir` can help. It uses [Avahi](http://avahi.org/) to find +where `pacredir` can help. It uses [Avahi ↗️](https://avahi.org/) to find other instances and get the files there if available. +*Use at your own risk*, pay attention to +[license and warranty](#license-and-warranty), and +[disclaimer on external links](#disclaimer-on-external-links)! + Requirements ------------ To compile and run `pacredir` you need: -* [systemd](https://www.github.com/systemd/systemd) -* [avahi](https://avahi.org/) -* [libmicrohttpd](https://www.gnu.org/software/libmicrohttpd/) -* [curl](https://curl.haxx.se/) -* [iniparser](https://github.com/ndevilla/iniparser) -* [darkhttpd](https://unix4lyfe.org/darkhttpd/) -* [markdown](https://daringfireball.net/projects/markdown/) (HTML documentation) +* [systemd ↗️](https://www.github.com/systemd/systemd) +* [avahi ↗️](https://avahi.org/) +* [libmicrohttpd ↗️](https://www.gnu.org/software/libmicrohttpd/) +* [curl ↗️](https://curl.haxx.se/) +* [iniparser ↗️](https://github.com/ndevilla/iniparser) +* [darkhttpd ↗️](https://unix4lyfe.org/darkhttpd/) +* [markdown ↗️](https://daringfireball.net/projects/markdown/) (HTML documentation) `Arch Linux` installs development files for the packages by default, so no additional development packages are required. @@ -42,8 +50,7 @@ followed by: This will place an executable at `/usr/bin/pacredir`, documentation can be found in `/usr/share/doc/pacredir/`. Additionally systemd service files are installed to -`/usr/lib/systemd/system/` and avahi service files go to -`/etc/avahi/services/`. +`/usr/lib/systemd/system/`. Usage ----- @@ -98,6 +105,21 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the [GNU General Public License](COPYING.md) for more details. +Disclaimer on external links +---------------------------- + +Our website contains links to the websites of third parties ("external +links"). As the content of these websites is not under our control, we +cannot assume any liability for such external content. In all cases, the +provider of information of the linked websites is liable for the content +and accuracy of the information provided. At the point in time when the +links were placed, no infringements of the law were recognisable to us. +As soon as an infringement of the law becomes known to us, we will +immediately remove the link in question. + +> 💡️ **Hint**: All external links are marked with an arrow pointing +> diagonally in an up-right (or north-east) direction (↗️). + ### Upstream URL: @@ -106,3 +128,6 @@ URL: Mirror: [eworm.de](https://git.eworm.de/cgit.cgi/pacredir/about/) [GitLab.com](https://gitlab.com/eworm-de/pacredir#pacredir) + +--- +[⬆️ Go back to top](#top) diff --git a/avahi/pacserve.service.in b/avahi/pacserve.service.in deleted file mode 100644 index 4a39e6d..0000000 --- a/avahi/pacserve.service.in +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" standalone='no'?><!--*-nxml-*--> -<!DOCTYPE service-group SYSTEM "avahi-service.dtd"> - -<!-- See avahi.service(5) for more information about this configuration file --> - -<service-group> - - <name replace-wildcards="yes">%h</name> - - <service> - <type>_pacserve_%ID%_%ARCH%._tcp</type> - <port>7078</port> - </service> - -</service-group> diff --git a/config.def.h b/config.def.h index 5fd7c13..4944ff9 100644 --- a/config.def.h +++ b/config.def.h @@ -1,5 +1,5 @@ /* - * (C) 2013-2024 by Christian Hesse <mail@eworm.de> + * (C) 2013-2025 by Christian Hesse <mail@eworm.de> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,7 +24,7 @@ #define DROP_PRIV_GID 65534 /* website url */ -#define WEBSITE "https://github.com/eworm-de/pacredir#pacredir" +#define WEBSITE "https://pacredir.eworm.de/" /* This is used for default documents. Usually you will not see this anyway. */ #define PAGE307 "<html><head><title>307 temporary redirect</title>" \ @@ -38,7 +38,7 @@ #define PORT_PACSERVE 7078 /* avahi service names */ -#define PACSERVE "_pacserve_" ID "_" ARCH "._tcp" +#define PACSERVE "_pacserve._tcp" /* path to the config file */ #define CONFIGFILE "/etc/pacredir.conf" diff --git a/initcpio/hooks/pacredir b/initcpio/hooks/pacredir deleted file mode 100644 index c73bb8e..0000000 --- a/initcpio/hooks/pacredir +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/sh - -run_latehook() { - local newroot="/new_root/" - - if ! grep -q '^pacserve hosts' ${newroot}/etc/pacredir.conf; then - case $(uname -m) in - x86_64) - if [[ -n "${pacserve_x86_64}" ]]; then - msg ":: Adding pacserve host '${pacserve_x86_64}' to pacredir.conf..." - echo "pacserve hosts = ${pacserve_x86_64}" >> ${newroot}/etc/pacredir.conf - fi - ;; - i686) - if [[ -n "${pacserve_i686}" ]]; then - msg ":: Adding pacserve host '${pacserve_i686}' to pacredir.conf..." - echo "pacserve hosts = ${pacserve_i686}" >> ${newroot}/etc/pacredir.conf - fi - ;; - esac - fi -} diff --git a/initcpio/install/pacredir b/initcpio/install/pacredir deleted file mode 100644 index 30d248f..0000000 --- a/initcpio/install/pacredir +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh - -build() { - add_runscript -} - -help() { - echo 'This hook adds peers to pacredir.conf from inside initramfs.' - echo 'Useless for installed systems, but can be handy with' - echo 'no-persistent configurations.' -} diff --git a/networkmanager/80-pacredir b/networkmanager/80-pacredir index 32114ae..fa9e1e1 100755 --- a/networkmanager/80-pacredir +++ b/networkmanager/80-pacredir @@ -1,6 +1,6 @@ #!/bin/sh -if [ "${2}" == "up" ]; then +if [ "${2}" = "up" ]; then if systemctl is-active -q pacredir.service; then systemctl reload pacredir.service fi @@ -1,5 +1,5 @@ /* - * (C) 2013-2024 by Christian Hesse <mail@eworm.de> + * (C) 2013-2025 by Christian Hesse <mail@eworm.de> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -181,13 +181,27 @@ static void resolve_callback(AvahiServiceResolver *r, break; case AVAHI_RESOLVER_FOUND: + if (!avahi_string_list_find(txt, "id=" ID)) { + if (verbose > 0) + write_log(stderr, "Service %s (port %d) on host %s on interface %s does not match id=" ID "\n", + type, port, host, intname); + break; + } + + if (!avahi_string_list_find(txt, "arch=" ARCH)) { + if (verbose > 0) + write_log(stderr, "Service %s (port %d) on host %s on interface %s does not match arch=" ARCH "\n", + type, port, host, intname); + break; + } + avahi_address_snprint(ipaddress, AVAHI_ADDRESS_STR_MAX, address); if (verbose > 0) - write_log(stdout, "Found service %s on host %s (%s) on interface %s\n", - type, host, ipaddress, intname); + write_log(stdout, "Found service %s (port %d) on host %s (%s) on interface %s\n", + type, port, host, ipaddress, intname); - add_host(host, protocol, ipaddress, PORT_PACSERVE, type); + add_host(host, protocol, ipaddress, port, type); break; } @@ -487,7 +501,7 @@ static mhd_result ahc_echo(void * cls, request->last_modified = 0; if (verbose > 0) - write_log(stdout, "Trying %s: %s\n", request->host, request->url); + write_log(stdout, "Trying %s: %s\n", request->host->host, request->url); if ((error = pthread_create(&tid[req_count], NULL, get_http_code, (void *)request)) != 0) write_log(stderr, "Could not run thread number %d, errno %d\n", req_count, error); @@ -675,7 +689,9 @@ int main(int argc, char ** argv) { /* Probing for static pacserve hosts takes some time. * Receiving a SIGHUP at this time could kill us. So register signal * SIGHUP here before probing. */ - signal(SIGHUP, sighup_callback); + struct sigaction act_hup = { 0 }; + act_hup.sa_handler = sighup_callback; + sigaction(SIGHUP, &act_hup, NULL); /* parse config file */ if ((ini = iniparser_load(CONFIGFILE)) == NULL) { @@ -774,7 +790,7 @@ int main(int argc, char ** argv) { /* prepare struct to make microhttpd listen on localhost only */ address.sin_family = AF_INET; address.sin_port = htons(PORT_PACREDIR); - address.sin_addr.s_addr = htonl(0x7f000001); + address.sin_addr.s_addr = htonl(INADDR_LOOPBACK); /* start http server */ if ((mhd = MHD_start_daemon(MHD_USE_THREAD_PER_CONNECTION | MHD_USE_TCP_FASTOPEN, PORT_PACREDIR, @@ -787,9 +803,11 @@ int main(int argc, char ** argv) { curl_global_init(CURL_GLOBAL_ALL); /* register SIG{TERM,KILL,INT} signal callbacks */ - signal(SIGTERM, sig_callback); - signal(SIGKILL, sig_callback); - signal(SIGINT, sig_callback); + struct sigaction act = { 0 }; + act.sa_handler = sig_callback; + sigaction(SIGTERM, &act, NULL); + sigaction(SIGKILL, &act, NULL); + sigaction(SIGINT, &act, NULL); /* report ready to systemd */ sd_notify(0, "READY=1\nSTATUS=Waiting for requests to redirect..."); @@ -1,5 +1,5 @@ /* - * (C) 2013-2024 by Christian Hesse <mail@eworm.de> + * (C) 2013-2025 by Christian Hesse <mail@eworm.de> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -41,6 +41,7 @@ #include <avahi-client/lookup.h> #include <avahi-common/error.h> #include <avahi-common/simple-watch.h> +#include <avahi-common/strlst.h> /* various headers needing linker options */ #include <curl/curl.h> diff --git a/pacserve.conf b/pacserve.conf new file mode 100644 index 0000000..6a0a279 --- /dev/null +++ b/pacserve.conf @@ -0,0 +1,4 @@ +# pacserve configuration file + +# Port to listen on +PORT=7078 diff --git a/systemd/pacredir.service b/systemd/pacredir.service index ed5e45a..9a5801f 100644 --- a/systemd/pacredir.service +++ b/systemd/pacredir.service @@ -1,4 +1,4 @@ -# (C) 2013-2024 by Christian Hesse <mail@eworm.de> +# (C) 2013-2025 by Christian Hesse <mail@eworm.de> # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -7,9 +7,9 @@ [Unit] Description=Redirect pacman requests via avahi service +Documentation=https://pacredir.eworm.de/ Requires=avahi-daemon.service After=avahi-daemon.service network.target network-online.target -Documentation=https://github.com/eworm-de/pacredir#pacredir [Service] Type=notify diff --git a/systemd/pacserve-announce.service.in b/systemd/pacserve-announce.service.in new file mode 100644 index 0000000..974a048 --- /dev/null +++ b/systemd/pacserve-announce.service.in @@ -0,0 +1,23 @@ +# (C) 2013-2025 by Christian Hesse <mail@eworm.de> +# Markus Weippert <markus@gekmihesg.de> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +[Unit] +Description=Announce pacman database files and package archives +Documentation=https://pacredir.eworm.de/ +After=avahi-daemon.service pacserve.service +BindsTo=pacserve.service +Requisite=avahi-daemon.service + +[Service] +EnvironmentFile=/etc/pacserve.conf +ExecStart=/usr/bin/avahi-publish -s "pacserve on %l" _pacserve._tcp ${PORT} id=%ID% arch=%ARCH% +DynamicUser=on +ProtectSystem=full +ProtectHome=on +PrivateDevices=on +NoNewPrivileges=on diff --git a/systemd/pacserve.service b/systemd/pacserve.service index d5e064d..2af4c1e 100644 --- a/systemd/pacserve.service +++ b/systemd/pacserve.service @@ -1,4 +1,4 @@ -# (C) 2013-2024 by Christian Hesse <mail@eworm.de> +# (C) 2013-2025 by Christian Hesse <mail@eworm.de> # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -7,10 +7,13 @@ [Unit] Description=Serve pacman database files and package archives +Documentation=https://pacredir.eworm.de/ After=systemd-tmpfiles-setup.service network.target +Upholds=pacserve-announce.service [Service] -ExecStart=/usr/bin/pacserve /run/pacserve/ --ipv6 --port 7078 --no-listing --index empty +EnvironmentFile=/etc/pacserve.conf +ExecStart=/usr/bin/pacserve /run/pacserve/ --ipv6 --port ${PORT} --no-listing --index empty BindReadOnlyPaths=/var/cache/pacman/pkg:/run/pacserve/pkg /var/lib/pacman/sync:/run/pacserve/db DynamicUser=on ProtectSystem=full diff --git a/systemd/sysusers.conf b/systemd/sysusers.conf index cd2e81c..ced5210 100644 --- a/systemd/sysusers.conf +++ b/systemd/sysusers.conf @@ -1 +1 @@ -u pacredir - "redirect pacman requests" +u! pacredir - "redirect pacman requests" |