Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
varnish-cache
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
varnishcache
varnish-cache
Commits
d8663956
Commit
d8663956
authored
Mar 11, 2015
by
Poul-Henning Kamp
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use the new VSS_resolver() function to handle IP's in VCC
parent
400744f2
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
120 additions
and
130 deletions
+120
-130
vcc_backend.c
lib/libvcc/vcc_backend.c
+9
-22
vcc_compile.h
lib/libvcc/vcc_compile.h
+2
-2
vcc_utils.c
lib/libvcc/vcc_utils.c
+109
-106
No files found.
lib/libvcc/vcc_backend.c
View file @
d8663956
...
...
@@ -35,8 +35,6 @@
#include "vcc_compile.h"
#include "vss.h"
/*--------------------------------------------------------------------
* Struct sockaddr is not really designed to be a compile time
* initialized data structure, so we encode it as a byte-string
...
...
@@ -44,27 +42,19 @@
*/
static
void
Emit_Sockaddr
(
struct
vcc
*
tl
,
const
struct
token
*
t_host
,
const
char
*
port
)
Emit_Sockaddr
(
struct
vcc
*
tl
,
const
struct
token
*
t_host
,
const
struct
token
*
t_port
)
{
const
char
*
ipv4
,
*
ipv4a
,
*
ipv6
,
*
ipv6a
,
*
pa
;
const
char
*
err
;
char
*
p
;
char
*
hop
,
*
pop
;
char
buf
[
256
];
AN
(
t_host
->
dec
);
p
=
TlDup
(
tl
,
t_host
->
dec
);
AN
(
p
);
err
=
VSS_parse
(
p
,
&
hop
,
&
pop
);
if
(
err
!=
NULL
)
{
VSB_printf
(
tl
->
sb
,
"Backend host '%.*s': %s
\n
"
,
PF
(
t_host
),
err
);
vcc_ErrWhere
(
tl
,
t_host
);
return
;
}
Resolve_Sockaddr
(
tl
,
hop
!=
NULL
?
hop
:
t_host
->
dec
,
pop
!=
NULL
?
pop
:
port
,
if
(
t_port
!=
NULL
)
bprintf
(
buf
,
"%s %s"
,
t_host
->
dec
,
t_port
->
dec
);
else
bprintf
(
buf
,
"%s"
,
t_host
->
dec
);
Resolve_Sockaddr
(
tl
,
buf
,
"http"
,
&
ipv4
,
&
ipv4a
,
&
ipv6
,
&
ipv6a
,
&
pa
,
2
,
t_host
,
"Backend host"
);
ERRCHK
(
tl
);
if
(
ipv4
!=
NULL
)
{
...
...
@@ -398,10 +388,7 @@ vcc_ParseHostDef(struct vcc *tl, const struct token *t_be)
/* Check that the hostname makes sense */
assert
(
t_host
!=
NULL
);
if
(
t_port
!=
NULL
)
Emit_Sockaddr
(
tl
,
t_host
,
t_port
->
dec
);
else
Emit_Sockaddr
(
tl
,
t_host
,
"80"
);
Emit_Sockaddr
(
tl
,
t_host
,
t_port
);
ERRCHK
(
tl
);
ExpectErr
(
tl
,
'}'
);
...
...
lib/libvcc/vcc_compile.h
View file @
d8663956
...
...
@@ -293,8 +293,8 @@ sym_wildcard_t vcc_Stv_Wildcard;
/* vcc_utils.c */
const
char
*
vcc_regexp
(
struct
vcc
*
tl
);
void
Resolve_Sockaddr
(
struct
vcc
*
tl
,
const
char
*
host
,
const
char
*
port
,
\
const
char
**
ipv4
,
const
char
**
ipv4_ascii
,
const
char
**
ipv6
,
\
void
Resolve_Sockaddr
(
struct
vcc
*
tl
,
const
char
*
host
,
const
char
*
defport
,
const
char
**
ipv4
,
const
char
**
ipv4_ascii
,
const
char
**
ipv6
,
const
char
**
ipv6_ascii
,
const
char
**
p_ascii
,
int
maxips
,
const
struct
token
*
t_err
,
const
char
*
errid
);
...
...
lib/libvcc/vcc_utils.c
View file @
d8663956
...
...
@@ -34,13 +34,14 @@
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include "vcc_compile.h"
#include "vre.h"
#include "vrt.h"
#include "vsa.h"
#include "vss.h"
#include "vtcp.h"
/*--------------------------------------------------------------------*/
...
...
@@ -94,37 +95,38 @@ vcc_regexp(struct vcc *tl)
* alignment.
*/
static
const
char
*
vcc_sockaddr
(
struct
vcc
*
tl
,
const
void
*
sa
,
unsigned
sal
)
static
void
vcc_suckaddr
(
struct
vcc
*
tl
,
const
char
*
host
,
const
struct
suckaddr
*
vsa
,
const
char
**
ip
,
const
char
**
ip_ascii
,
const
char
**
p_ascii
)
{
char
a
[
VTCP_ADDRBUFSIZE
];
char
p
[
VTCP_PORTBUFSIZE
];
const
int
sz
=
sizeof
(
unsigned
long
long
);
const
unsigned
n
=
(
vsa_suckaddr_len
+
sz
-
1
)
/
sz
;
unsigned
len
;
unsigned
long
long
b
[
n
];
struct
suckaddr
*
sua
;
char
*
p
;
int
len
;
char
*
q
;
AN
(
sa
);
AN
(
sal
);
sua
=
VSA_Malloc
(
sa
,
sal
);
AN
(
sua
);
VTCP_name
(
vsa
,
a
,
sizeof
a
,
p
,
sizeof
p
);
Fh
(
tl
,
0
,
"
\n
/*
\"
%s
\"
-> %s */
\n
"
,
host
,
a
);
if
(
ip_ascii
!=
NULL
)
*
ip_ascii
=
TlDup
(
tl
,
a
);
if
(
p_ascii
!=
NULL
&&
*
p_ascii
==
NULL
)
*
p_ascii
=
TlDup
(
tl
,
p
);
Fh
(
tl
,
0
,
"static const unsigned long long"
);
Fh
(
tl
,
0
,
" suckaddr_%u[%d] = {
\n
"
,
tl
->
unique
,
n
);
memcpy
(
b
,
sua
,
vsa_suckaddr_len
);
free
(
sua
);
memcpy
(
b
,
vsa
,
vsa_suckaddr_len
);
for
(
len
=
0
;
len
<
n
;
len
++
)
Fh
(
tl
,
0
,
"%s 0x%0*llxLL"
,
len
?
",
\n
"
:
""
,
sz
*
2
,
b
[
len
]);
Fh
(
tl
,
0
,
"
\n
};
\n
"
);
p
=
TlAlloc
(
tl
,
40
);
AN
(
p
);
sprintf
(
p
,
"(const void*)suckaddr_%u"
,
tl
->
unique
);
q
=
TlAlloc
(
tl
,
40
);
AN
(
q
);
sprintf
(
q
,
"(const void*)suckaddr_%u"
,
tl
->
unique
);
*
ip
=
q
;
tl
->
unique
++
;
return
(
p
);
}
/*--------------------------------------------------------------------
...
...
@@ -138,19 +140,57 @@ vcc_sockaddr(struct vcc *tl, const void *sa, unsigned sal)
* For backends, we accept up to one IPv4 and one IPv6.
*/
struct
foo_proto
{
const
char
*
name
;
int
family
;
struct
sockaddr_storage
sa
;
socklen_t
l
;
const
char
**
dst
;
const
char
**
dst_ascii
;
struct
rss
{
unsigned
magic
;
#define RSS_MAGIC 0x11e966ab
struct
suckaddr
*
vsa4
;
struct
suckaddr
*
vsa6
;
};
static
int
__match_proto__
(
resolved_f
)
rs_callback
(
void
*
priv
,
const
struct
suckaddr
*
vsa
)
{
struct
rss
*
rss
;
int
v
;
CAST_OBJ_NOTNULL
(
rss
,
priv
,
RSS_MAGIC
);
assert
(
VSA_Sane
(
vsa
));
v
=
VSA_Get_Proto
(
vsa
);
if
(
v
==
AF_INET
)
{
if
(
rss
->
vsa4
==
NULL
)
rss
->
vsa4
=
VSA_Clone
(
vsa
);
else
if
(
VSA_Compare
(
vsa
,
rss
->
vsa4
))
return
(
-
2
);
}
else
if
(
v
==
AF_INET6
)
{
if
(
rss
->
vsa6
==
NULL
)
rss
->
vsa6
=
VSA_Clone
(
vsa
);
else
if
(
VSA_Compare
(
vsa
,
rss
->
vsa6
))
return
(
-
2
);
}
else
{
WRONG
(
"Wrong protocol"
);
}
return
(
0
);
}
static
int
__match_proto__
(
resolved_f
)
rs_callback2
(
void
*
priv
,
const
struct
suckaddr
*
vsa
)
{
struct
vcc
*
tl
;
char
a
[
VTCP_ADDRBUFSIZE
];
char
p
[
VTCP_PORTBUFSIZE
];
CAST_OBJ_NOTNULL
(
tl
,
priv
,
VCC_MAGIC
);
VTCP_name
(
vsa
,
a
,
sizeof
a
,
p
,
sizeof
p
);
VSB_printf
(
tl
->
sb
,
"
\t
%s:%s
\n
"
,
a
,
p
);
return
(
0
);
}
void
Resolve_Sockaddr
(
struct
vcc
*
tl
,
const
char
*
host
,
const
char
*
port
,
const
char
*
def_
port
,
const
char
**
ipv4
,
const
char
**
ipv4_ascii
,
const
char
**
ipv6
,
...
...
@@ -160,100 +200,63 @@ Resolve_Sockaddr(struct vcc *tl,
const
struct
token
*
t_err
,
const
char
*
errid
)
{
struct
foo_proto
protos
[
3
],
*
pp
;
struct
addrinfo
*
res
,
*
res0
,
*
res1
,
hint
;
int
error
,
retval
;
char
hbuf
[
NI_MAXHOST
];
int
error
,
retval
=
0
;
struct
rss
*
rss
;
const
char
*
err
;
memset
(
protos
,
0
,
sizeof
protos
);
protos
[
0
].
name
=
"ipv4"
;
protos
[
0
].
family
=
PF_INET
;
protos
[
0
].
dst
=
ipv4
;
protos
[
0
].
dst_ascii
=
ipv4_ascii
;
*
ipv4
=
NULL
;
protos
[
1
].
name
=
"ipv6"
;
protos
[
1
].
family
=
PF_INET6
;
protos
[
1
].
dst
=
ipv6
;
protos
[
1
].
dst_ascii
=
ipv6_ascii
;
*
ipv6
=
NULL
;
if
(
p_ascii
!=
NULL
)
*
p_ascii
=
NULL
;
retval
=
0
;
memset
(
&
hint
,
0
,
sizeof
hint
);
hint
.
ai_family
=
PF_UNSPEC
;
hint
.
ai_socktype
=
SOCK_STREAM
;
ALLOC_OBJ
(
rss
,
RSS_MAGIC
);
AN
(
rss
);
error
=
getaddrinfo
(
host
,
port
,
&
hint
,
&
res0
);
if
(
error
)
{
VSB_printf
(
tl
->
sb
,
"%s '%.*s' could not be resolved to an IP address:
\n
"
,
errid
,
PF
(
t_err
));
error
=
VSS_resolver
(
host
,
def_port
,
rs_callback
,
rss
,
&
err
);
if
(
err
!=
NULL
)
{
VSB_printf
(
tl
->
sb
,
"%s '%.*s' could not be resolved to an IP address:
\n
"
"
\t
%s
\n
"
"(Sorry if that error message is gibberish.)
\n
"
,
gai_strerror
(
error
)
);
errid
,
PF
(
t_err
),
err
);
vcc_ErrWhere
(
tl
,
t_err
);
free
(
rss
->
vsa4
);
free
(
rss
->
vsa6
);
FREE_OBJ
(
rss
);
return
;
}
for
(
res
=
res0
;
res
;
res
=
res
->
ai_next
)
{
for
(
pp
=
protos
;
pp
->
name
!=
NULL
;
pp
++
)
if
(
res
->
ai_family
==
pp
->
family
)
break
;
if
(
pp
->
name
==
NULL
)
{
/* Unknown proto, ignore */
continue
;
}
if
(
pp
->
l
==
res
->
ai_addrlen
&&
!
memcmp
(
&
pp
->
sa
,
res
->
ai_addr
,
pp
->
l
))
{
/*
* Same address we already emitted.
* This can happen using /etc/hosts
*/
continue
;
}
if
(
pp
->
l
!=
0
||
retval
==
maxips
)
{
VSB_printf
(
tl
->
sb
,
"%s %.*s: resolves to too many addresses.
\n
"
"Only one IPv4 %s IPv6 are allowed.
\n
"
"Please specify which exact address "
"you want to use, we found all of these:
\n
"
,
errid
,
PF
(
t_err
),
maxips
>
1
?
"and one"
:
"or"
);
for
(
res1
=
res0
;
res1
!=
NULL
;
res1
=
res1
->
ai_next
)
{
error
=
getnameinfo
(
res1
->
ai_addr
,
res1
->
ai_addrlen
,
hbuf
,
sizeof
hbuf
,
NULL
,
0
,
NI_NUMERICHOST
);
AZ
(
error
);
VSB_printf
(
tl
->
sb
,
"
\t
%s
\n
"
,
hbuf
);
}
freeaddrinfo
(
res0
);
vcc_ErrWhere
(
tl
,
t_err
);
return
;
}
pp
->
l
=
res
->
ai_addrlen
;
assert
(
pp
->
l
<=
sizeof
(
struct
sockaddr_storage
));
memcpy
(
&
pp
->
sa
,
res
->
ai_addr
,
pp
->
l
);
error
=
getnameinfo
(
res
->
ai_addr
,
res
->
ai_addrlen
,
hbuf
,
sizeof
hbuf
,
NULL
,
0
,
NI_NUMERICHOST
);
AZ
(
error
);
Fh
(
tl
,
0
,
"
\n
/*
\"
%s
\"
-> %s */
\n
"
,
host
,
hbuf
);
*
(
pp
->
dst
)
=
vcc_sockaddr
(
tl
,
&
pp
->
sa
,
pp
->
l
);
if
(
pp
->
dst_ascii
!=
NULL
)
*
pp
->
dst_ascii
=
TlDup
(
tl
,
hbuf
);
if
(
rss
->
vsa4
!=
NULL
)
{
vcc_suckaddr
(
tl
,
host
,
rss
->
vsa4
,
ipv4
,
ipv4_ascii
,
p_ascii
);
free
(
rss
->
vsa4
);
retval
++
;
}
if
(
rss
->
vsa6
!=
NULL
)
{
vcc_suckaddr
(
tl
,
host
,
rss
->
vsa6
,
ipv6
,
ipv6_ascii
,
p_ascii
);
free
(
rss
->
vsa6
);
retval
++
;
}
if
(
p_ascii
!=
NULL
)
{
error
=
getnameinfo
(
res0
->
ai_addr
,
res0
->
ai_addrlen
,
NULL
,
0
,
hbuf
,
sizeof
hbuf
,
NI_NUMERICSERV
);
AZ
(
error
);
*
p_ascii
=
TlDup
(
tl
,
hbuf
);
FREE_OBJ
(
rss
);
if
(
error
==
-
2
||
retval
>
maxips
)
{
VSB_printf
(
tl
->
sb
,
"%s %.*s: resolves to too many addresses.
\n
"
"Only one IPv4 %s IPv6 are allowed.
\n
"
"Please specify which exact address "
"you want to use, we found all of these:
\n
"
,
errid
,
PF
(
t_err
),
maxips
>
1
?
"and one"
:
"or"
);
(
void
)
VSS_resolver
(
host
,
def_port
,
rs_callback2
,
tl
,
&
err
);
if
(
err
!=
NULL
)
{
VSB_printf
(
tl
->
sb
,
"%s '%.*s' could not be resolved to an"
" IP address:
\n
"
"
\t
%s
\n
"
"(Sorry if that error message is gibberish.)
\n
"
,
errid
,
PF
(
t_err
),
err
);
}
vcc_ErrWhere
(
tl
,
t_err
);
return
;
}
AZ
(
error
);
if
(
retval
==
0
)
{
VSB_printf
(
tl
->
sb
,
"%s '%.*s': resolves to "
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment