1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
|
pacredir
========
**pacredir - redirect pacman requests, assisted by avahi service discovery**
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
other instances and get the files there if available.
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)
`Arch Linux` installs development files for the packages by default, so
no additional development packages are required.
Build and install
-----------------
Building and installing is very easy. Just run:
> make
followed by:
> make install
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/`.
Usage
-----
Enable systemd services `pacserve` and `pacredir`, open TCP
port `7078` and add the following line to your repository
definitions in `pacman.conf`:
> Include = /etc/pacman.d/pacredir
Do not worry if `pacman` reports:
> error: failed retrieving file 'core.db' from 127.0.0.1:7077 : The
> requested URL returned error: 404 Not Found
This is ok, it just tells `pacman` that `pacredir` could not find a file
and downloading it from an official server is required.
Please note that `pacredir` redirects to the most recent database file
found on the local network if it is not too old (currently 24 hours). To
make sure you really do have the latest files run `pacman -Syu` *twice*.
To get a better idea what happens in the background have a look at
[the request flow chart](FLOW.md).
Current caveat
--------------
With its latest release `pacman` now supports a *server error limit*: Three
download errors from a server results in the server being skipped for the
remainder of this transaction.
However `pacredir` sends a "*404 - not found*" response if the file is not
available in local network - and is skipped after just three misses.
This new feature is not configurable at runtime, so rebuilding `pacman` with
one of the following patches is the way to make things work with `pacredir`.
### Disable server error limit
This is the simplest workaround - just disable the server error limit.
--- a/lib/libalpm/dload.c
+++ b/lib/libalpm/dload.c
@@ -60,7 +60,7 @@ static int curl_gethost(const char *url, char *buffer, size_t buf_len);
/* number of "soft" errors required to blacklist a server, set to 0 to disable
* server blacklisting */
-const unsigned int server_error_limit = 3;
+const unsigned int server_error_limit = 0;
struct server_error_count {
char server[HOSTNAME_SIZE];
We can agree this is not to be desired - in general the feature is reasonable.
### Support http header to indicate a soft failure
This solution is simple, yet powerful:
[Support http header 'Cache-Control: no-cache' for soft failure](patches/0001-support-http-header-Cache-Control-no-cache-for-soft-failure.patch)
By setting the HTTP header `Cache-Control: no-cache` when returning with
the status code `404` (not found) the server can indicate that this is a
soft failure. No error message is shown, and server's error count is
not increased.
Sadly upstream denied, again. 😢
Anyway, pushed this as merge request to Gitlab:
[support http header 'Cache-Control: no-cache' for soft failure](https://gitlab.archlinux.org/pacman/pacman/-/merge_requests/76)
### Implement CacheServer
A more complex solution that breaks current API is:
[Implement CacheServer](patches/0001-implement-CacheServer.patch)
This implements a new configuration option `CacheServer`. Adding a cache
server makes it ignore the server error limit.
Handling for soft failures is demanded in a long standing upstream bug, and
the given patch could solve it:
[FS#23407 - Allow soft failures on Server URLs](https://bugs.archlinux.org/task/23407)
Pushed this as merge request to Gitlab:
[implement CacheServer](https://gitlab.archlinux.org/pacman/pacman/-/merge_requests/74)
Security
--------
There is no security within this project, information and file content
is transferred unencrypted and unverified. Anybody is free to serve
broken and/or malicious files to you, but this is by design. So make
sure `pacman` is configured to check signatures! It will then detect if
anything goes wrong.
License and warranty
--------------------
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.
This program is distributed in the hope that it will be useful,
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.
### Upstream
URL:
[GitHub.com](https://github.com/eworm-de/pacredir#pacredir)
Mirror:
[eworm.de](https://git.eworm.de/cgit.cgi/pacredir/about/)
[GitLab.com](https://gitlab.com/eworm-de/pacredir#pacredir)
|