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
a646c8f6
Commit
a646c8f6
authored
Apr 08, 2015
by
Poul-Henning Kamp
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add ProxyV2 support.
parent
89ca131f
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
296 additions
and
10 deletions
+296
-10
cache_proxy_proto.c
bin/varnishd/proxy/cache_proxy_proto.c
+127
-10
o00001.vtc
bin/varnishtest/tests/o00001.vtc
+169
-0
No files found.
bin/varnishd/proxy/cache_proxy_proto.c
View file @
a646c8f6
...
...
@@ -32,6 +32,8 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdlib.h>
#include <string.h>
...
...
@@ -40,11 +42,7 @@
#include "vend.h"
#include "vsa.h"
static
const
char
vpx2_sig
[]
=
{
'\r'
,
'\n'
,
'\r'
,
'\n'
,
'\0'
,
'\r'
,
'\n'
,
'Q'
,
'U'
,
'I'
,
'T'
,
'\n'
,
};
#include "vtcp.h"
/**********************************************************************
* PROXY 1 protocol
...
...
@@ -60,7 +58,7 @@ vpx_proto1(const struct worker *wrk, struct req *req)
char
*
p
,
*
q
;
struct
addrinfo
hints
,
*
res
;
struct
suckaddr
*
sa
;
int
pfam
=
0
;
int
pfam
=
-
1
;
CHECK_OBJ_NOTNULL
(
wrk
,
WORKER_MAGIC
);
CHECK_OBJ_NOTNULL
(
req
,
REQ_MAGIC
);
...
...
@@ -156,21 +154,139 @@ vpx_proto1(const struct worker *wrk, struct req *req)
return
(
0
);
}
/**********************************************************************
* PROXY 2 protocol
*/
static
const
char
vpx2_sig
[]
=
{
'\r'
,
'\n'
,
'\r'
,
'\n'
,
'\0'
,
'\r'
,
'\n'
,
'Q'
,
'U'
,
'I'
,
'T'
,
'\n'
,
};
static
int
vpx_proto2
(
const
struct
worker
*
wrk
,
struct
req
*
req
)
{
int
l
;
const
uint8_t
*
p
;
sa_family_t
pfam
=
0xff
;
struct
sockaddr_in
sin4
;
struct
sockaddr_in6
sin6
;
struct
suckaddr
*
sa
=
NULL
;
char
hb
[
VTCP_ADDRBUFSIZE
];
char
pb
[
VTCP_PORTBUFSIZE
];
CHECK_OBJ_NOTNULL
(
wrk
,
WORKER_MAGIC
);
CHECK_OBJ_NOTNULL
(
req
,
REQ_MAGIC
);
VSL
(
SLT_Debug
,
req
->
sp
->
fd
,
"PROXY2"
);
assert
(
req
->
htc
->
rxbuf_e
-
req
->
htc
->
rxbuf_b
>=
16
);
assert
(
req
->
htc
->
rxbuf_e
-
req
->
htc
->
rxbuf_b
>=
16
L
);
l
=
vbe16dec
(
req
->
htc
->
rxbuf_b
+
14
);
req
->
htc
->
pipeline_b
=
req
->
htc
->
rxbuf_b
+
16
+
l
;
assert
(
req
->
htc
->
rxbuf_e
-
req
->
htc
->
rxbuf_b
>=
16L
+
l
);
req
->
htc
->
pipeline_b
=
req
->
htc
->
rxbuf_b
+
16L
+
l
;
p
=
(
const
void
*
)
req
->
htc
->
rxbuf_b
;
/* Version @12 top half */
if
((
p
[
12
]
>>
4
)
!=
2
)
{
VSLb
(
req
->
vsl
,
SLT_ProxyGarbage
,
"PROXY2: bad version (%d)"
,
p
[
12
]
>>
4
);
return
(
-
1
);
}
/* Command @12 bottom half */
switch
(
p
[
12
]
&
0x0f
)
{
case
0x0
:
/* Local connection from proxy, ignore addresses */
return
(
0
);
case
0x1
:
/* Proxied connection */
break
;
default:
VSLb
(
req
->
vsl
,
SLT_ProxyGarbage
,
"PROXY2: bad command (%d)"
,
p
[
12
]
&
0x0f
);
return
(
-
1
);
}
/* Address family & protocol @13 */
switch
(
p
[
13
])
{
case
0x00
:
/* UNSPEC|UNSPEC, ignore proxy header */
VSLb
(
req
->
vsl
,
SLT_ProxyGarbage
,
"PROXY2: Ignoring UNSPEC|UNSPEC addresses"
);
return
(
0
);
case
0x11
:
/* IPv4|TCP */
pfam
=
AF_INET
;
if
(
l
<
12
)
{
VSLb
(
req
->
vsl
,
SLT_ProxyGarbage
,
"PROXY2: Ignoring short IPv4 addresses (%d)"
,
l
);
return
(
0
);
}
break
;
case
0x21
:
/* IPv6|TCP */
pfam
=
AF_INET6
;
if
(
l
<
36
)
{
VSLb
(
req
->
vsl
,
SLT_ProxyGarbage
,
"PROXY2: Ignoring short IPv6 addresses (%d)"
,
l
);
return
(
0
);
}
break
;
default:
/* Ignore proxy header */
VSLb
(
req
->
vsl
,
SLT_ProxyGarbage
,
"PROXY2: Ignoring unsupported protocol (0x%02x)"
,
p
[
13
]);
return
(
0
);
}
switch
(
pfam
)
{
case
AF_INET
:
memset
(
&
sin4
,
0
,
sizeof
sin4
);
sin4
.
sin_family
=
pfam
;
/* dst/server */
memcpy
(
&
sin4
.
sin_addr
,
p
+
20
,
4
);
memcpy
(
&
sin4
.
sin_port
,
p
+
26
,
2
);
SES_Reserve_server_addr
(
req
->
sp
,
&
sa
);
AN
(
VSA_Build
(
sa
,
&
sin4
,
sizeof
sin4
));
/* src/client */
memcpy
(
&
sin4
.
sin_addr
,
p
+
16
,
4
);
memcpy
(
&
sin4
.
sin_port
,
p
+
24
,
2
);
SES_Reserve_client_addr
(
req
->
sp
,
&
sa
);
AN
(
VSA_Build
(
sa
,
&
sin4
,
sizeof
sin4
));
break
;
case
AF_INET6
:
memset
(
&
sin6
,
0
,
sizeof
sin6
);
sin6
.
sin6_family
=
pfam
;
/* dst/server */
memcpy
(
&
sin6
.
sin6_addr
,
p
+
32
,
16
);
memcpy
(
&
sin6
.
sin6_port
,
p
+
50
,
2
);
SES_Reserve_server_addr
(
req
->
sp
,
&
sa
);
AN
(
VSA_Build
(
sa
,
&
sin6
,
sizeof
sin6
));
/* src/client */
memcpy
(
&
sin6
.
sin6_addr
,
p
+
16
,
16
);
memcpy
(
&
sin6
.
sin6_port
,
p
+
48
,
2
);
SES_Reserve_client_addr
(
req
->
sp
,
&
sa
);
AN
(
VSA_Build
(
sa
,
&
sin6
,
sizeof
sin6
));
break
;
default:
WRONG
(
"Wrong pfam"
);
}
AN
(
sa
);
VTCP_name
(
sa
,
hb
,
sizeof
hb
,
pb
,
sizeof
pb
);
SES_Set_String_Attr
(
req
->
sp
,
SA_CLIENT_IP
,
hb
);
SES_Set_String_Attr
(
req
->
sp
,
SA_CLIENT_PORT
,
pb
);
VSLb
(
req
->
vsl
,
SLT_Debug
,
"PROXY2 %s %s"
,
hb
,
pb
);
return
(
0
);
}
/**********************************************************************
* HTC_Rx completion detector
*/
static
enum
htc_status_e
__match_proto__
(
htc_complete_f
)
vpx_complete
(
struct
http_conn
*
htc
)
{
...
...
@@ -192,6 +308,8 @@ vpx_complete(struct http_conn *htc)
if
(
j
==
0
)
return
(
HTC_S_JUNK
);
if
(
j
==
1
&&
i
==
sizeof
vpx1_sig
)
{
if
(
l
>
107
)
return
(
HTC_S_OVERFLOW
);
if
(
strchr
(
p
+
i
,
'\n'
)
==
NULL
)
return
(
HTC_S_MORE
);
return
(
HTC_S_COMPLETE
);
...
...
@@ -208,7 +326,6 @@ vpx_complete(struct http_conn *htc)
return
(
HTC_S_MORE
);
}
void
__match_proto__
(
task_func_t
)
VPX_Proto_Sess
(
struct
worker
*
wrk
,
void
*
priv
)
{
...
...
bin/varnishtest/tests/o00001.vtc
0 → 100644
View file @
a646c8f6
varnishtest "PROXY v2 test"
server s1 {
# The server address is part of the hash-key
# so we need three responses
rxreq
expect req.http.x-forwarded-for == "127.0.0.1"
txresp -hdr "Obj: 1"
rxreq
expect req.http.x-forwarded-for == "1.2.3.4"
txresp -hdr "Obj: 2"
rxreq
expect req.http.x-forwarded-for == "102:304:506::d0e:f10"
txresp -hdr "Obj: 3"
} -start
varnish v1 -proto "PROXY" -vcl+backend {
import ${vmod_std};
acl fwd_client {
"1.2.3.4";
"102:304:506::d0e:f10";
}
acl fwd_server {
"5.6.7.8";
"8182:8384:8586::8d8e:8f80";
}
sub vcl_deliver {
set resp.http.li = local.ip;
set resp.http.lp = std.port(local.ip);
set resp.http.ri = remote.ip;
set resp.http.rp = std.port(remote.ip);
set resp.http.ci = client.ip;
set resp.http.cp = std.port(client.ip);
set resp.http.si = server.ip;
set resp.http.sp = std.port(server.ip);
set resp.http.fc = (client.ip ~ fwd_client);
set resp.http.fs = (server.ip ~ fwd_server);
}
} -start
client c1 {
# LOCAL command
sendhex "0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a"
sendhex "20 00 00 00"
txreq
rxresp
expect resp.status == 200
expect resp.http.si == "${v1_addr}"
expect resp.http.sp == "${v1_port}"
expect resp.http.ci == "127.0.0.1"
} -run
delay .1
client c1 {
# unknown command
sendhex "0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a"
sendhex "22 00 00 00"
timeout 8
expect_close
} -run
delay .1
client c1 {
# UNSPEC proto
sendhex "0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a"
sendhex "21 00 00 00"
txreq
rxresp
expect resp.status == 200
expect resp.http.si == "${v1_addr}"
expect resp.http.sp == "${v1_port}"
expect resp.http.ci == "127.0.0.1"
} -run
delay .1
client c1 {
# unknown proto
sendhex "0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a"
sendhex "21 99 00 00"
txreq
rxresp
expect resp.status == 200
expect resp.http.si == "${v1_addr}"
expect resp.http.sp == "${v1_port}"
expect resp.http.ci == "127.0.0.1"
} -run
delay .1
client c1 {
# short IPv4
sendhex "0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a"
sendhex "21 11 00 0b"
sendhex "01 02 03 04 05 06 07 08 09 0a 0b"
txreq
rxresp
expect resp.status == 200
expect resp.http.si == "${v1_addr}"
expect resp.http.sp == "${v1_port}"
expect resp.http.ci == "127.0.0.1"
} -run
delay .1
client c1 {
# short IPv6
sendhex "0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a"
sendhex "21 21 00 23"
sendhex "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f"
sendhex "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f"
sendhex "01 02 03"
txreq
rxresp
expect resp.status == 200
expect resp.http.fs == false
expect resp.http.fc == false
expect resp.http.si == "${v1_addr}"
expect resp.http.sp == "${v1_port}"
expect resp.http.ci == "127.0.0.1"
} -run
delay .1
client c1 {
# good IPv4
sendhex "0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a"
sendhex "21 11 00 0c"
sendhex "01 02 03 04"
sendhex "05 06 07 08"
sendhex "09 0a"
sendhex "0b 0c"
txreq
rxresp
expect resp.status == 200
expect resp.http.obj == 2
expect resp.http.fs == true
expect resp.http.fc == true
expect resp.http.ci == "1.2.3.4"
expect resp.http.cp == "2314"
expect resp.http.si == "5.6.7.8"
expect resp.http.sp == "2828"
expect resp.http.li == "${v1_addr}"
expect resp.http.lp == "${v1_port}"
expect resp.http.ri != "1.2.3.4"
} -run
delay .1
client c1 {
# good IPv6
sendhex "0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a"
sendhex "21 21 00 24"
sendhex "01 02 03 04 05 06 00 00 00 00 00 00 0d 0e 0f 10"
sendhex "81 82 83 84 85 86 00 00 00 00 00 00 8d 8e 8f 80"
sendhex "09 0a"
sendhex "0b 0c"
txreq
rxresp
expect resp.status == 200
expect resp.http.obj == 3
expect resp.http.fs == true
expect resp.http.fc == true
expect resp.http.ci == "102:304:506::d0e:f10"
expect resp.http.cp == "2314"
expect resp.http.si == "8182:8384:8586::8d8e:8f80"
expect resp.http.sp == "2828"
expect resp.http.li == "${v1_addr}"
expect resp.http.lp == "${v1_port}"
expect resp.http.ri != "102:304:506::d0e:f10"
} -run
delay .1
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