~ubuntu-branches/ubuntu/saucy/varnish/saucy

« back to all changes in this revision

Viewing changes to lib/libvcl/vcc_backend.c

  • Committer: Bazaar Package Importer
  • Author(s): Stig Sandbeck Mathisen
  • Date: 2011-03-21 10:16:07 UTC
  • mfrom: (24.1.2 experimental)
  • Revision ID: james.westby@ubuntu.com-20110321101607-528fzl583fqanas5
Tags: 2.1.5-2
ReleaseĀ forĀ unstable

Show diffs side-by-side

added added

removed removed

Lines of Context:
51
51
#include "config.h"
52
52
 
53
53
#include "svnid.h"
54
 
SVNID("$Id: vcc_backend.c 5041 2010-07-13 09:10:48Z tfheen $")
 
54
SVNID("$Id$")
55
55
 
56
56
#include <sys/types.h>
57
57
#include <sys/socket.h>
60
60
#include <netdb.h>
61
61
#include <stdio.h>
62
62
#include <stdarg.h>
 
63
#include <stdlib.h>
63
64
#include <string.h>
64
65
 
65
66
#include "vsb.h"
 
67
#include "vss.h"
66
68
 
67
69
#include "vcc_priv.h"
68
70
#include "vcc_compile.h"
74
76
        char                    *vgcname;
75
77
};
76
78
 
77
 
static const char *
78
 
CheckHostPort(const char *host, const char *port)
 
79
static int
 
80
emit_sockaddr(struct tokenlist *tl, void *sa, unsigned sal)
79
81
{
80
 
        struct addrinfo *res, hint;
81
 
        int error;
 
82
        unsigned len;
 
83
        uint8_t *u;
82
84
 
83
 
        memset(&hint, 0, sizeof hint);
84
 
        hint.ai_family = PF_UNSPEC;
85
 
        hint.ai_socktype = SOCK_STREAM;
86
 
        error = getaddrinfo(host, port, &hint, &res);
87
 
        if (error)
88
 
                return (gai_strerror(error));
89
 
        freeaddrinfo(res);
90
 
        return (NULL);
 
85
        AN(sa);
 
86
        AN(sal);
 
87
        assert(sal < 256);
 
88
        Fh(tl, 0, "\nstatic const unsigned char sockaddr%u[%d] = {\n",
 
89
            tl->nsockaddr, sal + 1);
 
90
        Fh(tl, 0, "    %3u, /* Length */\n",  sal);
 
91
        u = sa;
 
92
        for (len = 0; len <sal; len++) {
 
93
                if ((len % 8) == 0)
 
94
                        Fh(tl, 0, "   ");
 
95
                Fh(tl, 0, " %3u", u[len]);
 
96
                if (len + 1 < sal)
 
97
                        Fh(tl, 0, ",");
 
98
                if ((len % 8) == 7)
 
99
                        Fh(tl, 0, "\n");
 
100
        }
 
101
        Fh(tl, 0, "\n};\n");
 
102
        return (tl->nsockaddr++);
91
103
}
92
104
 
93
105
/*--------------------------------------------------------------------
96
108
 * and put it in an official sockaddr when we load the VCL.
97
109
 */
98
110
 
99
 
static void
 
111
#include <stdio.h>
 
112
 
 
113
void
100
114
Emit_Sockaddr(struct tokenlist *tl, const struct token *t_host,
101
115
    const char *port)
 
116
 
102
117
{
103
118
        struct addrinfo *res, *res0, *res1, hint;
104
 
        int n4, n6, len, error, retval;
 
119
        int n4, n6, error, retval, x;
105
120
        const char *emit, *multiple;
106
 
        unsigned char *u;
107
121
        char hbuf[NI_MAXHOST];
 
122
        char *hop, *pop;
108
123
 
109
124
        AN(t_host->dec);
110
125
        retval = 0;
111
126
        memset(&hint, 0, sizeof hint);
112
127
        hint.ai_family = PF_UNSPEC;
113
128
        hint.ai_socktype = SOCK_STREAM;
114
 
        error = getaddrinfo(t_host->dec, port, &hint, &res0);
 
129
 
 
130
        if (VSS_parse(t_host->dec, &hop, &pop)) {
 
131
                vsb_printf(tl->sb,
 
132
                    "Backend host '%.*s': wrong syntax (unbalanced [...] ?)\n",
 
133
                    PF(t_host) );
 
134
                vcc_ErrWhere(tl, t_host);
 
135
                return;
 
136
        }
 
137
        if (pop != NULL)
 
138
                error = getaddrinfo(hop, pop, &hint, &res0);
 
139
        else
 
140
                error = getaddrinfo(t_host->dec, port, &hint, &res0);
 
141
        free(hop);
 
142
        free(pop);
 
143
        if (error) {
 
144
                vsb_printf(tl->sb,
 
145
                    "Backend host '%.*s'"
 
146
                    " could not be resolved to an IP address:\n", PF(t_host));
 
147
                vsb_printf(tl->sb,
 
148
                    "\t%s\n"
 
149
                    "(Sorry if that error message is gibberish.)\n",
 
150
                    gai_strerror(error));
 
151
                vcc_ErrWhere(tl, t_host);
 
152
                return;
 
153
        }
115
154
        AZ(error);
116
155
        n4 = n6 = 0;
117
156
        multiple = NULL;
 
157
 
118
158
        for (res = res0; res; res = res->ai_next) {
119
159
                emit = NULL;
120
160
                if (res->ai_family == PF_INET) {
121
161
                        if (n4++ == 0)
122
 
                                emit = "ipv4_sockaddr";
 
162
                                emit = "ipv4";
123
163
                        else
124
164
                                multiple = "IPv4";
125
165
                } else if (res->ai_family == PF_INET6) {
126
166
                        if (n6++ == 0)
127
 
                                emit = "ipv6_sockaddr";
 
167
                                emit = "ipv6";
128
168
                        else
129
169
                                multiple = "IPv6";
130
170
                } else
149
189
                        return;
150
190
                }
151
191
                AN(emit);
152
 
                AN(res->ai_addr);
153
 
                AN(res->ai_addrlen);
154
 
                assert(res->ai_addrlen < 256);
155
 
                Fh(tl, 0, "\nstatic const unsigned char sockaddr%u[%d] = {\n",
156
 
                    tl->nsockaddr, res->ai_addrlen + 1);
157
 
                Fh(tl, 0, "    %3u, /* Length */\n",  res->ai_addrlen);
158
 
                u = (void*)res->ai_addr;
159
 
                for (len = 0; len < res->ai_addrlen; len++) {
160
 
                        if ((len % 8) == 0)
161
 
                                Fh(tl, 0, "   ");
162
 
                        Fh(tl, 0, " %3u", u[len]);
163
 
                        if (len + 1 < res->ai_addrlen)
164
 
                                Fh(tl, 0, ",");
165
 
                        if ((len % 8) == 7)
166
 
                                Fh(tl, 0, "\n");
167
 
                }
168
 
                Fh(tl, 0, "\n};\n");
169
 
                Fb(tl, 0, "\t.%s = sockaddr%u,\n", emit, tl->nsockaddr++);
 
192
                x = emit_sockaddr(tl, res->ai_addr, res->ai_addrlen);
 
193
                Fb(tl, 0, "\t.%s_sockaddr = sockaddr%u,\n", emit, x);
 
194
                error = getnameinfo(res->ai_addr,
 
195
                    res->ai_addrlen, hbuf, sizeof hbuf,
 
196
                    NULL, 0, NI_NUMERICHOST);
 
197
                AZ(error);
 
198
                Fb(tl, 0, "\t.%s_addr = \"%s\",\n", emit, hbuf);
170
199
                retval++;
171
200
        }
 
201
        if (res0 != NULL) {
 
202
                error = getnameinfo(res0->ai_addr,
 
203
                    res0->ai_addrlen, NULL, 0, hbuf, sizeof hbuf,
 
204
                    NI_NUMERICSERV);
 
205
                AZ(error);
 
206
                Fb(tl, 0, "\t.port = \"%s\",\n", hbuf);
 
207
        }
172
208
        freeaddrinfo(res0);
173
209
        if (retval == 0) {
174
210
                vsb_printf(tl->sb,
189
225
 * in that context.
190
226
 */
191
227
 
192
 
static void
 
228
void
193
229
vcc_EmitBeIdent(const struct tokenlist *tl, struct vsb *v,
194
230
    int serial, const struct token *first, const struct token *last)
195
231
{
389
425
        struct token *t_port = NULL;
390
426
        struct token *t_hosthdr = NULL;
391
427
        unsigned saint = UINT_MAX;
392
 
        const char *ep;
393
428
        struct fld_spec *fs;
394
429
        struct vsb *vsb;
395
430
        unsigned u;
511
546
 
512
547
        /* Check that the hostname makes sense */
513
548
        assert(t_host != NULL);
514
 
        ep = CheckHostPort(t_host->dec, "80");
515
 
        if (ep != NULL) {
516
 
                vsb_printf(tl->sb, "Backend host '%.*s': %s\n", PF(t_host), ep);
517
 
                vcc_ErrWhere(tl, t_host);
518
 
                return;
519
 
        }
520
 
 
521
 
        /* Check that the portname makes sense */
522
 
        if (t_port != NULL) {
523
 
                ep = CheckHostPort("127.0.0.1", t_port->dec);
524
 
                if (ep != NULL) {
525
 
                        vsb_printf(tl->sb,
526
 
                            "Backend port '%.*s': %s\n", PF(t_port), ep);
527
 
                        vcc_ErrWhere(tl, t_port);
528
 
                        return;
529
 
                }
 
549
        if (t_port != NULL) 
530
550
                Emit_Sockaddr(tl, t_host, t_port->dec);
531
 
        } else {
 
551
        else
532
552
                Emit_Sockaddr(tl, t_host, "80");
533
 
        }
534
553
        ERRCHK(tl);
535
554
 
536
555
        ExpectErr(tl, '}');
662
681
        { "random",             vcc_ParseRandomDirector },
663
682
        { "client",             vcc_ParseRandomDirector },
664
683
        { "round-robin",        vcc_ParseRoundRobinDirector },
 
684
        { "dns",                vcc_ParseDnsDirector },
665
685
        { NULL,         NULL }
666
686
};
667
687