[PATCH] Provide access to git_dir through get_git_dir().
[git] / daemon.c
1 #include "cache.h"
2 #include "pkt-line.h"
3 #include <signal.h>
4 #include <sys/wait.h>
5 #include <sys/socket.h>
6 #include <sys/time.h>
7 #include <netdb.h>
8 #include <netinet/in.h>
9 #include <arpa/inet.h>
10 #include <syslog.h>
11
12 static int log_syslog;
13 static int verbose;
14
15 static const char daemon_usage[] = "git-daemon [--verbose] [--syslog] [--inetd | --port=n]";
16
17
18 static void logreport(int priority, const char *err, va_list params)
19 {
20         /* We should do a single write so that it is atomic and output
21          * of several processes do not get intermingled. */
22         char buf[1024];
23         int buflen;
24         int maxlen, msglen;
25
26         /* sizeof(buf) should be big enough for "[pid] \n" */
27         buflen = snprintf(buf, sizeof(buf), "[%ld] ", (long) getpid());
28
29         maxlen = sizeof(buf) - buflen - 1; /* -1 for our own LF */
30         msglen = vsnprintf(buf + buflen, maxlen, err, params);
31
32         if (log_syslog) {
33                 syslog(priority, "%s", buf);
34                 return;
35         }
36
37         /* maxlen counted our own LF but also counts space given to
38          * vsnprintf for the terminating NUL.  We want to make sure that
39          * we have space for our own LF and NUL after the "meat" of the
40          * message, so truncate it at maxlen - 1.
41          */
42         if (msglen > maxlen - 1)
43                 msglen = maxlen - 1;
44         else if (msglen < 0)
45                 msglen = 0; /* Protect against weird return values. */
46         buflen += msglen;
47
48         buf[buflen++] = '\n';
49         buf[buflen] = '\0';
50
51         write(2, buf, buflen);
52 }
53
54 void logerror(const char *err, ...)
55 {
56         va_list params;
57         va_start(params, err);
58         logreport(LOG_ERR, err, params);
59         va_end(params);
60 }
61
62 void loginfo(const char *err, ...)
63 {
64         va_list params;
65         if (!verbose)
66                 return;
67         va_start(params, err);
68         logreport(LOG_INFO, err, params);
69         va_end(params);
70 }
71
72
73 static int upload(char *dir, int dirlen)
74 {
75         loginfo("Request for '%s'", dir);
76         if (chdir(dir) < 0) {
77                 logerror("Cannot chdir('%s'): %s", dir, strerror(errno));
78                 return -1;
79         }
80         chdir(".git");
81
82         /*
83          * Security on the cheap.
84          *
85          * We want a readable HEAD, usable "objects" directory, and 
86          * a "git-daemon-export-ok" flag that says that the other side
87          * is ok with us doing this.
88          */
89         if (access("git-daemon-export-ok", F_OK) ||
90             access("objects/00", X_OK) ||
91             access("HEAD", R_OK)) {
92                 logerror("Not a valid gitd-enabled repository: '%s'", dir);
93                 return -1;
94         }
95
96         /*
97          * We'll ignore SIGTERM from now on, we have a
98          * good client.
99          */
100         signal(SIGTERM, SIG_IGN);
101
102         /* git-upload-pack only ever reads stuff, so this is safe */
103         execlp("git-upload-pack", "git-upload-pack", ".", NULL);
104         return -1;
105 }
106
107 static int execute(void)
108 {
109         static char line[1000];
110         int len;
111
112         len = packet_read_line(0, line, sizeof(line));
113
114         if (len && line[len-1] == '\n')
115                 line[--len] = 0;
116
117         if (!strncmp("git-upload-pack /", line, 17))
118                 return upload(line + 16, len - 16);
119
120         logerror("Protocol error: '%s'", line);
121         return -1;
122 }
123
124
125 /*
126  * We count spawned/reaped separately, just to avoid any
127  * races when updating them from signals. The SIGCHLD handler
128  * will only update children_reaped, and the fork logic will
129  * only update children_spawned.
130  *
131  * MAX_CHILDREN should be a power-of-two to make the modulus
132  * operation cheap. It should also be at least twice
133  * the maximum number of connections we will ever allow.
134  */
135 #define MAX_CHILDREN 128
136
137 static int max_connections = 25;
138
139 /* These are updated by the signal handler */
140 static volatile unsigned int children_reaped = 0;
141 static pid_t dead_child[MAX_CHILDREN];
142
143 /* These are updated by the main loop */
144 static unsigned int children_spawned = 0;
145 static unsigned int children_deleted = 0;
146
147 static struct child {
148         pid_t pid;
149         int addrlen;
150         struct sockaddr_storage address;
151 } live_child[MAX_CHILDREN];
152
153 static void add_child(int idx, pid_t pid, struct sockaddr *addr, int addrlen)
154 {
155         live_child[idx].pid = pid;
156         live_child[idx].addrlen = addrlen;
157         memcpy(&live_child[idx].address, addr, addrlen);
158 }
159
160 /*
161  * Walk from "deleted" to "spawned", and remove child "pid".
162  *
163  * We move everything up by one, since the new "deleted" will
164  * be one higher.
165  */
166 static void remove_child(pid_t pid, unsigned deleted, unsigned spawned)
167 {
168         struct child n;
169
170         deleted %= MAX_CHILDREN;
171         spawned %= MAX_CHILDREN;
172         if (live_child[deleted].pid == pid) {
173                 live_child[deleted].pid = -1;
174                 return;
175         }
176         n = live_child[deleted];
177         for (;;) {
178                 struct child m;
179                 deleted = (deleted + 1) % MAX_CHILDREN;
180                 if (deleted == spawned)
181                         die("could not find dead child %d\n", pid);
182                 m = live_child[deleted];
183                 live_child[deleted] = n;
184                 if (m.pid == pid)
185                         return;
186                 n = m;
187         }
188 }
189
190 /*
191  * This gets called if the number of connections grows
192  * past "max_connections".
193  *
194  * We _should_ start off by searching for connections
195  * from the same IP, and if there is some address wth
196  * multiple connections, we should kill that first.
197  *
198  * As it is, we just "randomly" kill 25% of the connections,
199  * and our pseudo-random generator sucks too. I have no
200  * shame.
201  *
202  * Really, this is just a place-holder for a _real_ algorithm.
203  */
204 static void kill_some_children(int signo, unsigned start, unsigned stop)
205 {
206         start %= MAX_CHILDREN;
207         stop %= MAX_CHILDREN;
208         while (start != stop) {
209                 if (!(start & 3))
210                         kill(live_child[start].pid, signo);
211                 start = (start + 1) % MAX_CHILDREN;
212         }
213 }
214
215 static void check_max_connections(void)
216 {
217         for (;;) {
218                 int active;
219                 unsigned spawned, reaped, deleted;
220
221                 spawned = children_spawned;
222                 reaped = children_reaped;
223                 deleted = children_deleted;
224
225                 while (deleted < reaped) {
226                         pid_t pid = dead_child[deleted % MAX_CHILDREN];
227                         remove_child(pid, deleted, spawned);
228                         deleted++;
229                 }
230                 children_deleted = deleted;
231
232                 active = spawned - deleted;
233                 if (active <= max_connections)
234                         break;
235
236                 /* Kill some unstarted connections with SIGTERM */
237                 kill_some_children(SIGTERM, deleted, spawned);
238                 if (active <= max_connections << 1)
239                         break;
240
241                 /* If the SIGTERM thing isn't helping use SIGKILL */
242                 kill_some_children(SIGKILL, deleted, spawned);
243                 sleep(1);
244         }
245 }
246
247 static void handle(int incoming, struct sockaddr *addr, int addrlen)
248 {
249         pid_t pid = fork();
250         char addrbuf[256] = "";
251         int port = -1;
252
253         if (pid) {
254                 unsigned idx;
255
256                 close(incoming);
257                 if (pid < 0)
258                         return;
259
260                 idx = children_spawned % MAX_CHILDREN;
261                 children_spawned++;
262                 add_child(idx, pid, addr, addrlen);
263
264                 check_max_connections();
265                 return;
266         }
267
268         dup2(incoming, 0);
269         dup2(incoming, 1);
270         close(incoming);
271
272         if (addr->sa_family == AF_INET) {
273                 struct sockaddr_in *sin_addr = (void *) addr;
274                 inet_ntop(AF_INET, &sin_addr->sin_addr, addrbuf, sizeof(addrbuf));
275                 port = sin_addr->sin_port;
276
277         } else if (addr->sa_family == AF_INET6) {
278                 struct sockaddr_in6 *sin6_addr = (void *) addr;
279
280                 char *buf = addrbuf;
281                 *buf++ = '['; *buf = '\0'; /* stpcpy() is cool */
282                 inet_ntop(AF_INET6, &sin6_addr->sin6_addr, buf, sizeof(addrbuf) - 1);
283                 strcat(buf, "]");
284
285                 port = sin6_addr->sin6_port;
286         }
287         loginfo("Connection from %s:%d", addrbuf, port);
288
289         exit(execute());
290 }
291
292 static void child_handler(int signo)
293 {
294         for (;;) {
295                 int status;
296                 pid_t pid = waitpid(-1, &status, WNOHANG);
297
298                 if (pid > 0) {
299                         unsigned reaped = children_reaped;
300                         dead_child[reaped % MAX_CHILDREN] = pid;
301                         children_reaped = reaped + 1;
302                         /* XXX: Custom logging, since we don't wanna getpid() */
303                         if (verbose) {
304                                 char *dead = "";
305                                 if (!WIFEXITED(status) || WEXITSTATUS(status) > 0)
306                                         dead = " (with error)";
307                                 if (log_syslog)
308                                         syslog(LOG_INFO, "[%d] Disconnected%s", pid, dead);
309                                 else
310                                         fprintf(stderr, "[%d] Disconnected%s\n", pid, dead);
311                         }
312                         continue;
313                 }
314                 break;
315         }
316 }
317
318 static int serve(int port)
319 {
320         struct addrinfo hints, *ai0, *ai;
321         int gai;
322         int socknum = 0, *socklist = NULL;
323         int maxfd = -1;
324         fd_set fds_init, fds;
325         char pbuf[NI_MAXSERV];
326
327         signal(SIGCHLD, child_handler);
328
329         sprintf(pbuf, "%d", port);
330         memset(&hints, 0, sizeof(hints));
331         hints.ai_family = AF_UNSPEC;
332         hints.ai_socktype = SOCK_STREAM;
333         hints.ai_protocol = IPPROTO_TCP;
334         hints.ai_flags = AI_PASSIVE;
335
336         gai = getaddrinfo(NULL, pbuf, &hints, &ai0);
337         if (gai)
338                 die("getaddrinfo() failed: %s\n", gai_strerror(gai));
339
340         FD_ZERO(&fds_init);
341
342         for (ai = ai0; ai; ai = ai->ai_next) {
343                 int sockfd;
344                 int *newlist;
345
346                 sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
347                 if (sockfd < 0)
348                         continue;
349                 if (sockfd >= FD_SETSIZE) {
350                         error("too large socket descriptor.");
351                         close(sockfd);
352                         continue;
353                 }
354
355 #ifdef IPV6_V6ONLY
356                 if (ai->ai_family == AF_INET6) {
357                         int on = 1;
358                         setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY,
359                                    &on, sizeof(on));
360                         /* Note: error is not fatal */
361                 }
362 #endif
363
364                 if (bind(sockfd, ai->ai_addr, ai->ai_addrlen) < 0) {
365                         close(sockfd);
366                         continue;       /* not fatal */
367                 }
368                 if (listen(sockfd, 5) < 0) {
369                         close(sockfd);
370                         continue;       /* not fatal */
371                 }
372
373                 newlist = realloc(socklist, sizeof(int) * (socknum + 1));
374                 if (!newlist)
375                         die("memory allocation failed: %s", strerror(errno));
376
377                 socklist = newlist;
378                 socklist[socknum++] = sockfd;
379
380                 FD_SET(sockfd, &fds_init);
381                 if (maxfd < sockfd)
382                         maxfd = sockfd;
383         }
384
385         freeaddrinfo(ai0);
386
387         if (socknum == 0)
388                 die("unable to allocate any listen sockets on port %u", port);
389
390         for (;;) {
391                 int i;
392                 fds = fds_init;
393                 
394                 if (select(maxfd + 1, &fds, NULL, NULL, NULL) < 0) {
395                         if (errno != EINTR) {
396                                 error("select failed, resuming: %s",
397                                       strerror(errno));
398                                 sleep(1);
399                         }
400                         continue;
401                 }
402
403                 for (i = 0; i < socknum; i++) {
404                         int sockfd = socklist[i];
405
406                         if (FD_ISSET(sockfd, &fds)) {
407                                 struct sockaddr_storage ss;
408                                 int sslen = sizeof(ss);
409                                 int incoming = accept(sockfd, (struct sockaddr *)&ss, &sslen);
410                                 if (incoming < 0) {
411                                         switch (errno) {
412                                         case EAGAIN:
413                                         case EINTR:
414                                         case ECONNABORTED:
415                                                 continue;
416                                         default:
417                                                 die("accept returned %s", strerror(errno));
418                                         }
419                                 }
420                                 handle(incoming, (struct sockaddr *)&ss, sslen);
421                         }
422                 }
423         }
424 }
425
426 int main(int argc, char **argv)
427 {
428         int port = DEFAULT_GIT_PORT;
429         int inetd_mode = 0;
430         int i;
431
432         for (i = 1; i < argc; i++) {
433                 char *arg = argv[i];
434
435                 if (!strncmp(arg, "--port=", 7)) {
436                         char *end;
437                         unsigned long n;
438                         n = strtoul(arg+7, &end, 0);
439                         if (arg[7] && !*end) {
440                                 port = n;
441                                 continue;
442                         }
443                 }
444
445                 if (!strcmp(arg, "--inetd")) {
446                         inetd_mode = 1;
447                         continue;
448                 }
449                 if (!strcmp(arg, "--verbose")) {
450                         verbose = 1;
451                         continue;
452                 }
453                 if (!strcmp(arg, "--syslog")) {
454                         log_syslog = 1;
455                         openlog("git-daemon", 0, LOG_DAEMON);
456                         continue;
457                 }
458
459                 usage(daemon_usage);
460         }
461
462         if (inetd_mode) {
463                 fclose(stderr); //FIXME: workaround
464                 return execute();
465         }
466
467         return serve(port);
468 }