Skip to content

Commit 673d49e

Browse files
committed
Support the proxy protocol, close bfenetworks#11
1 parent 0b6725a commit 673d49e

25 files changed

+2566
-65
lines changed

bfe_basic/request.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,8 @@ func NewRequest(request *bfe_http.Request, conn net.Conn, stat *RequestStat,
113113
fReq.Context = make(map[interface{}]interface{})
114114
fReq.Tags.TagTable = make(map[string][]string)
115115

116-
if conn != nil {
117-
fReq.RemoteAddr = conn.RemoteAddr().(*net.TCPAddr)
116+
if session != nil {
117+
fReq.RemoteAddr = session.RemoteAddr
118118
}
119119

120120
fReq.SvrDataConf = svrDataConf

bfe_config/bfe_conf/conf_basic.go

+26-2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@ import (
2727
"github.com/baidu/bfe/bfe_util"
2828
)
2929

30+
const (
31+
BALANCER_BGW = "BGW" // layer4 balancer in baidu
32+
BALANCER_PROXY = "PROXY" // layer4 balancer working in PROXY mode (eg. F5, Ctrix, ELB etc)
33+
BALANCER_NONE = "NONE" // layer4 balancer not used
34+
)
35+
3036
type ConfigBasic struct {
3137
HttpPort int // listen port for http
3238
HttpsPort int // listen port for https
@@ -43,6 +49,7 @@ type ConfigBasic struct {
4349
GracefulShutdownTimeout int // graceful shutdown timeout, in seconds
4450
MaxHeaderBytes int // max header length in bytes in request
4551
MaxHeaderUriBytes int // max URI(in header) length in bytes in request
52+
MaxProxyHeaderBytes int // max header lenght in bytes in Proxy protocol
4653
KeepAliveEnabled bool // if false, client connection is shutdown disregard of http headers
4754

4855
Modules []string // modules to load
@@ -117,8 +124,8 @@ func basicConfCheck(cfg *ConfigBasic) error {
117124
}
118125

119126
// check Layer4LoadBalancer
120-
if cfg.Layer4LoadBalancer != "BGW" && cfg.Layer4LoadBalancer != "" {
121-
return fmt.Errorf("Layer4LoadBalancer[%s] not support", cfg.Layer4LoadBalancer)
127+
if err := checkLayer4LoadBalancer(cfg); err != nil {
128+
return err
122129
}
123130

124131
// check TlsHandshakeTimeout
@@ -175,6 +182,23 @@ func basicConfCheck(cfg *ConfigBasic) error {
175182
return nil
176183
}
177184

185+
func checkLayer4LoadBalancer(cfg *ConfigBasic) error {
186+
if len(cfg.Layer4LoadBalancer) == 0 {
187+
cfg.Layer4LoadBalancer = BALANCER_BGW // default BGW
188+
}
189+
190+
switch cfg.Layer4LoadBalancer {
191+
case BALANCER_BGW:
192+
return nil
193+
case BALANCER_PROXY:
194+
return nil
195+
case BALANCER_NONE:
196+
return nil
197+
default:
198+
return fmt.Errorf("Layer4LoadBalancer[%s] should be BGW/PROXY/NONE", cfg.Layer4LoadBalancer)
199+
}
200+
}
201+
178202
func dataFileConfCheck(cfg *ConfigBasic, confRoot string) error {
179203
// check HostRuleConf
180204
if cfg.HostRuleConf == "" {

bfe_modules/mod_header/action_header_var.go

+54-4
Original file line numberDiff line numberDiff line change
@@ -19,24 +19,35 @@ import (
1919
"encoding/asn1"
2020
"encoding/hex"
2121
"fmt"
22+
"net"
2223
"os"
2324
"strconv"
2425
)
2526

2627
import (
2728
"github.com/baidu/bfe/bfe_basic"
2829
"github.com/baidu/bfe/bfe_tls"
30+
"github.com/baidu/bfe/bfe_util"
2931
)
3032

3133
type HeaderValueHandler func(req *bfe_basic.Request) string
3234

35+
const (
36+
UNKNOWN = "unknown"
37+
)
38+
3339
var VariableHandlers = map[string]HeaderValueHandler{
3440
// for client
3541
"bfe_client_ip": getClientIp,
3642
"bfe_client_port": getClientPort,
3743
"bfe_request_host": getRequestHost,
38-
"bfe_session_id": getSessionId,
39-
"bfe_vip": getBfeVip,
44+
45+
// for conn info
46+
"bfe_session_id": getSessionId,
47+
"bfe_cip": getClientIp, // client ip (alias for bfe_clientip)
48+
"bfe_vip": getBfeVip, // virtual ip
49+
"bfe_bip": getBfeBip, // balancer ip
50+
"bfe_rip": getBfeRip, // bfe ip
4051

4152
// for bfe
4253
"bfe_server_name": getBfeServerName,
@@ -240,7 +251,46 @@ func getBfeVip(req *bfe_basic.Request) string {
240251
return req.Session.Vip.String()
241252
}
242253

243-
return "unknown"
254+
return UNKNOWN
255+
}
256+
257+
func getAddressFetcher(conn net.Conn) bfe_util.AddressFetcher {
258+
if c, ok := conn.(*bfe_tls.Conn); ok {
259+
conn = c.GetNetConn()
260+
}
261+
if f, ok := conn.(bfe_util.AddressFetcher); ok {
262+
return f
263+
}
264+
return nil
265+
}
266+
267+
func getBfeBip(req *bfe_basic.Request) string {
268+
f := getAddressFetcher(req.Session.Connection)
269+
if f == nil {
270+
return UNKNOWN
271+
}
272+
273+
baddr := f.BalancerAddr()
274+
if baddr == nil {
275+
return UNKNOWN
276+
}
277+
bip, _, err := net.SplitHostPort(baddr.String())
278+
if err != nil { /* never come here */
279+
return UNKNOWN
280+
}
281+
282+
return bip
283+
}
284+
285+
func getBfeRip(req *bfe_basic.Request) string {
286+
conn := req.Session.Connection
287+
raddr := conn.LocalAddr()
288+
rip, _, err := net.SplitHostPort(raddr.String())
289+
if err != nil { /* never come here */
290+
return UNKNOWN
291+
}
292+
293+
return rip
244294
}
245295

246296
func getBfeBackendInfo(req *bfe_basic.Request) string {
@@ -252,7 +302,7 @@ func getBfeBackendInfo(req *bfe_basic.Request) string {
252302
func getBfeServerName(req *bfe_basic.Request) string {
253303
hostname, err := os.Hostname()
254304
if err != nil {
255-
return "unknown"
305+
return UNKNOWN
256306
}
257307

258308
return hostname

bfe_proxy/addr_proto.go

+116
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
// Copyright (c) 2019 Baidu, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
// Copyright (c) pires.
16+
//
17+
// Licensed under the Apache License, Version 2.0 (the "License");
18+
// you may not use this file except in compliance with the License.
19+
// You may obtain a copy of the License at
20+
//
21+
// http://www.apache.org/licenses/LICENSE-2.0
22+
//
23+
// Unless required by applicable law or agreed to in writing, software
24+
// distributed under the License is distributed on an "AS IS" BASIS,
25+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
26+
// See the License for the specific language governing permissions and
27+
// limitations under the License.
28+
29+
package bfe_proxy
30+
31+
// AddressFamilyAndProtocol represents address family and transport protocol.
32+
type AddressFamilyAndProtocol byte
33+
34+
const (
35+
UNSPEC = '\x00'
36+
TCPv4 = '\x11'
37+
UDPv4 = '\x12'
38+
TCPv6 = '\x21'
39+
UDPv6 = '\x22'
40+
UnixStream = '\x31'
41+
UnixDatagram = '\x32'
42+
)
43+
44+
var supportedTransportProtocol = map[AddressFamilyAndProtocol]bool{
45+
TCPv4: true,
46+
UDPv4: true,
47+
TCPv6: true,
48+
UDPv6: true,
49+
UnixStream: true,
50+
UnixDatagram: true,
51+
}
52+
53+
// IsIPv4 returns true if the address family is IPv4 (AF_INET4), false otherwise.
54+
func (ap AddressFamilyAndProtocol) IsIPv4() bool {
55+
return 0x10 == ap&0xF0
56+
}
57+
58+
// IsIPv6 returns true if the address family is IPv6 (AF_INET6), false otherwise.
59+
func (ap AddressFamilyAndProtocol) IsIPv6() bool {
60+
return 0x20 == ap&0xF0
61+
}
62+
63+
// IsUnix returns true if the address family is UNIX (AF_UNIX), false otherwise.
64+
func (ap AddressFamilyAndProtocol) IsUnix() bool {
65+
return 0x30 == ap&0xF0
66+
}
67+
68+
// IsStream returns true if the transport protocol is TCP or STREAM (SOCK_STREAM), false otherwise.
69+
func (ap AddressFamilyAndProtocol) IsStream() bool {
70+
return 0x01 == ap&0x0F
71+
}
72+
73+
// IsDatagram returns true if the transport protocol is UDP or DGRAM (SOCK_DGRAM), false otherwise.
74+
func (ap AddressFamilyAndProtocol) IsDatagram() bool {
75+
return 0x02 == ap&0x0F
76+
}
77+
78+
// IsUnspec returns true if the transport protocol or address family is unspecified, false otherwise.
79+
func (ap AddressFamilyAndProtocol) IsUnspec() bool {
80+
return (0x00 == ap&0xF0) || (0x00 == ap&0x0F)
81+
}
82+
83+
func (ap AddressFamilyAndProtocol) toByte() byte {
84+
if ap.IsIPv4() && ap.IsStream() {
85+
return TCPv4
86+
} else if ap.IsIPv4() && ap.IsDatagram() {
87+
return UDPv4
88+
} else if ap.IsIPv6() && ap.IsStream() {
89+
return TCPv6
90+
} else if ap.IsIPv6() && ap.IsDatagram() {
91+
return UDPv6
92+
} else if ap.IsUnix() && ap.IsStream() {
93+
return UnixStream
94+
} else if ap.IsUnix() && ap.IsDatagram() {
95+
return UnixDatagram
96+
}
97+
98+
return UNSPEC
99+
}
100+
101+
func (ap AddressFamilyAndProtocol) String() string {
102+
if ap.IsIPv4() && ap.IsStream() {
103+
return "tcp4"
104+
} else if ap.IsIPv4() && ap.IsDatagram() {
105+
return "udp4"
106+
} else if ap.IsIPv6() && ap.IsStream() {
107+
return "tcp6"
108+
} else if ap.IsIPv6() && ap.IsDatagram() {
109+
return "udp6"
110+
} else if ap.IsUnix() && ap.IsStream() {
111+
return "unix"
112+
} else if ap.IsUnix() && ap.IsDatagram() {
113+
return "unixgram"
114+
}
115+
return "unspec"
116+
}

0 commit comments

Comments
 (0)