daemon: deglobalize hostname information
Move the variables related to the client-supplied hostname into its own struct, let execute() own an instance of that instead of storing the information in global variables and pass the struct to any function that needs to access it as a parameter. The lifetime of the variables is easier to see this way. Allocated memory is released within execute(). The strbufs don't have to be reset anymore because they are written to only once at most: parse_host_arg() is only called once by execute() and lookup_hostname() guards against being called twice using hostname_lookup_done. Signed-off-by: Rene Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
René Scharfe committed
Mar 7, 2015 at 11:50 UTC
01cec54e135c6c70bf6e1e197590749076e7cdfd
1 file changed
+74
-59
daemon.c
+74
-59
@@ -43,9 +43,6 @@ static const char *base_path;
43
static const char *interpolated_path;
44
static int base_path_relaxed;
45
46
-/* Flag indicating client sent extra args. */
47
-static int saw_extended_args;
48
-
46
/* If defined, ~user notation is allowed and the string is inserted
47
* after ~user/. E.g. a request to git://host/~alice/frotz would
48
* go to /home/alice/pub_git/frotz with --user-path=pub_git.
@@ -56,25 +53,27 @@ static const char *user_path;
53
static unsigned int timeout;
54
static unsigned int init_timeout;
55
59
-static struct strbuf hostname = STRBUF_INIT;
60
-static struct strbuf canon_hostname = STRBUF_INIT;
61
-static struct strbuf ip_address = STRBUF_INIT;
62
-static struct strbuf tcp_port = STRBUF_INIT;
63
-
64
-static int hostname_lookup_done;
56
+struct hostinfo {
57
+ struct strbuf hostname;
58
+ struct strbuf canon_hostname;
59
+ struct strbuf ip_address;
60
+ struct strbuf tcp_port;
61
+ unsigned int hostname_lookup_done:1;
62
+ unsigned int saw_extended_args:1;
63
+};
64
66
-static void lookup_hostname(void);
65
+static void lookup_hostname(struct hostinfo *hi);
66
68
-static const char *get_canon_hostname(void)
67
+static const char *get_canon_hostname(struct hostinfo *hi)
68
{
70
- lookup_hostname();
71
- return canon_hostname.buf;
69
+ lookup_hostname(hi);
70
+ return hi->canon_hostname.buf;
71
}
72
74
-static const char *get_ip_address(void)
73
+static const char *get_ip_address(struct hostinfo *hi)
74
{
76
- lookup_hostname();
77
- return ip_address.buf;
75
+ lookup_hostname(hi);
76
+ return hi->ip_address.buf;
77
}
78
79
static void logreport(int priority, const char *err, va_list params)
@@ -124,30 +123,32 @@ static void NORETURN daemon_die(const char *err, va_list params)
123
124
struct expand_path_context {
125
const char *directory;
126
+ struct hostinfo *hostinfo;
127
};
128
129
static size_t expand_path(struct strbuf *sb, const char *placeholder, void *ctx)
130
{
131
struct expand_path_context *context = ctx;
132
+ struct hostinfo *hi = context->hostinfo;
133
134
switch (placeholder[0]) {
135
case 'H':
135
- strbuf_addbuf(sb, &hostname);
136
+ strbuf_addbuf(sb, &hi->hostname);
137
return 1;
138
case 'C':
139
if (placeholder[1] == 'H') {
139
- strbuf_addstr(sb, get_canon_hostname());
140
+ strbuf_addstr(sb, get_canon_hostname(hi));
141
return 2;
142
}
143
break;
144
case 'I':
145
if (placeholder[1] == 'P') {
145
- strbuf_addstr(sb, get_ip_address());
146
+ strbuf_addstr(sb, get_ip_address(hi));
147
return 2;
148
}
149
break;
150
case 'P':
150
- strbuf_addbuf(sb, &tcp_port);
151
+ strbuf_addbuf(sb, &hi->tcp_port);
152
return 1;
153
case 'D':
154
strbuf_addstr(sb, context->directory);
@@ -156,7 +157,7 @@ static size_t expand_path(struct strbuf *sb, const char *placeholder, void *ctx)
157
return 0;
158
}
159
159
-static const char *path_ok(const char *directory)
160
+static const char *path_ok(const char *directory, struct hostinfo *hi)
161
{
162
static char rpath[PATH_MAX];
163
static char interp_path[PATH_MAX];
@@ -192,11 +193,12 @@ static const char *path_ok(const char *directory)
193
dir = rpath;
194
}
195
}
195
- else if (interpolated_path && saw_extended_args) {
196
+ else if (interpolated_path && hi->saw_extended_args) {
197
struct strbuf expanded_path = STRBUF_INIT;
198
struct expand_path_context context;
199
200
context.directory = directory;
201
+ context.hostinfo = hi;
202
203
if (*dir != '/') {
204
/* Allow only absolute */
@@ -286,7 +288,8 @@ static int daemon_error(const char *dir, const char *msg)
288
289
static const char *access_hook;
290
289
-static int run_access_hook(struct daemon_service *service, const char *dir, const char *path)
291
+static int run_access_hook(struct daemon_service *service, const char *dir,
292
+ const char *path, struct hostinfo *hi)
293
{
294
struct child_process child = CHILD_PROCESS_INIT;
295
struct strbuf buf = STRBUF_INIT;
@@ -298,10 +301,10 @@ static int run_access_hook(struct daemon_service *service, const char *dir, cons
301
*arg++ = access_hook;
302
*arg++ = service->name;
303
*arg++ = path;
301
- *arg++ = hostname.buf;
302
- *arg++ = get_canon_hostname();
303
- *arg++ = get_ip_address();
304
- *arg++ = tcp_port.buf;
304
+ *arg++ = hi->hostname.buf;
305
+ *arg++ = get_canon_hostname(hi);
306
+ *arg++ = get_ip_address(hi);
307
+ *arg++ = hi->tcp_port.buf;
308
*arg = NULL;
309
310
child.use_shell = 1;
@@ -346,7 +349,8 @@ error_return:
349
return -1;
350
}
351
349
-static int run_service(const char *dir, struct daemon_service *service)
352
+static int run_service(const char *dir, struct daemon_service *service,
353
+ struct hostinfo *hi)
354
{
355
const char *path;
356
int enabled = service->enabled;
@@ -360,7 +364,7 @@ static int run_service(const char *dir, struct daemon_service *service)
364
return daemon_error(dir, "service not enabled");
365
}
366
363
- if (!(path = path_ok(dir)))
367
+ if (!(path = path_ok(dir, hi)))
368
return daemon_error(dir, "no such repository");
369
370
/*
@@ -396,7 +400,7 @@ static int run_service(const char *dir, struct daemon_service *service)
400
* Optionally, a hook can choose to deny access to the
401
* repository depending on the phase of the moon.
402
*/
399
- if (access_hook && run_access_hook(service, dir, path))
403
+ if (access_hook && run_access_hook(service, dir, path, hi))
404
return -1;
405
406
/*
@@ -561,14 +565,14 @@ static void canonicalize_client(struct strbuf *out, const char *in)
565
/*
566
* Read the host as supplied by the client connection.
567
*/
564
-static void parse_host_arg(char *extra_args, int buflen)
568
+static void parse_host_arg(struct hostinfo *hi, char *extra_args, int buflen)
569
{
570
char *val;
571
int vallen;
572
char *end = extra_args + buflen;
573
574
if (extra_args < end && *extra_args) {
571
- saw_extended_args = 1;
575
+ hi->saw_extended_args = 1;
576
if (strncasecmp("host=", extra_args, 5) == 0) {
577
val = extra_args + 5;
578
vallen = strlen(val) + 1;
@@ -577,13 +581,10 @@ static void parse_host_arg(char *extra_args, int buflen)
581
char *host;
582
char *port;
583
parse_host_and_port(val, &host, &port);
580
- if (port) {
581
- strbuf_reset(&tcp_port);
582
- sanitize_client(&tcp_port, port);
583
- }
584
- strbuf_reset(&hostname);
585
- canonicalize_client(&hostname, host);
586
- hostname_lookup_done = 0;
584
+ if (port)
585
+ sanitize_client(&hi->tcp_port, port);
586
+ canonicalize_client(&hi->hostname, host);
587
+ hi->hostname_lookup_done = 0;
588
}
589
590
/* On to the next one */
@@ -597,9 +598,9 @@ static void parse_host_arg(char *extra_args, int buflen)
598
/*
599
* Locate canonical hostname and its IP address.
600
*/
600
-static void lookup_hostname(void)
601
+static void lookup_hostname(struct hostinfo *hi)
602
{
602
- if (!hostname_lookup_done && hostname.len) {
603
+ if (!hi->hostname_lookup_done && hi->hostname.len) {
604
#ifndef NO_IPV6
605
struct addrinfo hints;
606
struct addrinfo *ai;
@@ -609,21 +610,20 @@ static void lookup_hostname(void)
610
memset(&hints, 0, sizeof(hints));
611
hints.ai_flags = AI_CANONNAME;
612
612
- gai = getaddrinfo(hostname.buf, NULL, &hints, &ai);
613
+ gai = getaddrinfo(hi->hostname.buf, NULL, &hints, &ai);
614
if (!gai) {
615
struct sockaddr_in *sin_addr = (void *)ai->ai_addr;
616
617
inet_ntop(AF_INET, &sin_addr->sin_addr,
618
addrbuf, sizeof(addrbuf));
618
- strbuf_reset(&ip_address);
619
- strbuf_addstr(&ip_address, addrbuf);
619
+ strbuf_addstr(&hi->ip_address, addrbuf);
620
621
- strbuf_reset(&canon_hostname);
621
if (ai->ai_canonname)
623
- sanitize_client(&canon_hostname,
622
+ sanitize_client(&hi->canon_hostname,
623
ai->ai_canonname);
624
else
626
- strbuf_addbuf(&canon_hostname, &ip_address);
625
+ strbuf_addbuf(&hi->canon_hostname,
626
+ &hi->ip_address);
627
628
freeaddrinfo(ai);
629
}
@@ -644,22 +644,39 @@ static void lookup_hostname(void)
644
inet_ntop(hent->h_addrtype, &sa.sin_addr,
645
addrbuf, sizeof(addrbuf));
646
647
- strbuf_reset(&canon_hostname);
648
- sanitize_client(&canon_hostname, hent->h_name);
649
- strbuf_reset(&ip_address);
650
- strbuf_addstr(&ip_address, addrbuf);
647
+ sanitize_client(&hi->canon_hostname, hent->h_name);
648
+ strbuf_addstr(&hi->ip_address, addrbuf);
649
}
650
#endif
653
- hostname_lookup_done = 1;
651
+ hi->hostname_lookup_done = 1;
652
}
653
}
654
655
+static void hostinfo_init(struct hostinfo *hi)
656
+{
657
+ memset(hi, 0, sizeof(*hi));
658
+ strbuf_init(&hi->hostname, 0);
659
+ strbuf_init(&hi->canon_hostname, 0);
660
+ strbuf_init(&hi->ip_address, 0);
661
+ strbuf_init(&hi->tcp_port, 0);
662
+}
663
+
664
+static void hostinfo_clear(struct hostinfo *hi)
665
+{
666
+ strbuf_release(&hi->hostname);
667
+ strbuf_release(&hi->canon_hostname);
668
+ strbuf_release(&hi->ip_address);
669
+ strbuf_release(&hi->tcp_port);
670
+}
671
672
static int execute(void)
673
{
674
char *line = packet_buffer;
675
int pktlen, len, i;
676
char *addr = getenv("REMOTE_ADDR"), *port = getenv("REMOTE_PORT");
677
+ struct hostinfo hi;
678
+
679
+ hostinfo_init(&hi);
680
681
if (addr)
682
loginfo("Connection from %s:%s", addr, port);
@@ -678,13 +695,8 @@ static int execute(void)
695
pktlen--;
696
}
697
681
- strbuf_release(&hostname);
682
- strbuf_release(&canon_hostname);
683
- strbuf_release(&ip_address);
684
- strbuf_release(&tcp_port);
685
-
698
if (len != pktlen)
687
- parse_host_arg(line + len + 1, pktlen - len - 1);
699
+ parse_host_arg(&hi, line + len + 1, pktlen - len - 1);
700
701
for (i = 0; i < ARRAY_SIZE(daemon_service); i++) {
702
struct daemon_service *s = &(daemon_service[i]);
@@ -697,10 +709,13 @@ static int execute(void)
709
* Note: The directory here is probably context sensitive,
710
* and might depend on the actual service being performed.
711
*/
700
- return run_service(arg, s);
712
+ int rc = run_service(arg, s, &hi);
713
+ hostinfo_clear(&hi);
714
+ return rc;
715
}
716
}
717
718
+ hostinfo_clear(&hi);
719
logerror("Protocol error: '%s'", line);
720
return -1;
721
}