Skip to content

Commit

Permalink
Remove legacy Layer4LoadBalancer option (bfenetworks#448)
Browse files Browse the repository at this point in the history
  • Loading branch information
tianxinheihei authored Apr 30, 2020
1 parent 4496d15 commit 2edd981
Show file tree
Hide file tree
Showing 8 changed files with 12 additions and 263 deletions.
5 changes: 1 addition & 4 deletions bfe_config/bfe_conf/conf_basic.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import (
)

const (
BalancerBgw = "BGW" // layer4 balancer in baidu
BalancerProxy = "PROXY" // layer4 balancer working in PROXY mode (eg. F5, Ctrix, ELB etc)
BalancerNone = "NONE" // layer4 balancer not used
)
Expand Down Expand Up @@ -234,14 +233,12 @@ func checkLayer4LoadBalancer(cfg *ConfigBasic) error {
}

switch cfg.Layer4LoadBalancer {
case BalancerBgw:
return nil
case BalancerProxy:
return nil
case BalancerNone:
return nil
default:
return fmt.Errorf("Layer4LoadBalancer[%s] should be BGW/PROXY/NONE", cfg.Layer4LoadBalancer)
return fmt.Errorf("Layer4LoadBalancer[%s] should be PROXY/NONE", cfg.Layer4LoadBalancer)
}
}

Expand Down
11 changes: 3 additions & 8 deletions bfe_server/bfe_listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@
// limitations under the License.

// BfeListener is a wapper of TCP listener which accept connections behind
// a load balancer (BGW/PROXY/NONE)
// a load balancer (PROXY/NONE)
//
// Note: The TLS listener is wired together like:
// 1. TCP listener
// 2. BFE listener (BGW/PROXY)
// 2. BFE listener (PROXY)
// 3. TLS listener

package bfe_server
Expand All @@ -30,15 +30,14 @@ import (
import (
"github.com/baidu/bfe/bfe_config/bfe_conf"
"github.com/baidu/bfe/bfe_proxy"
"github.com/baidu/bfe/bfe_util"
)

import (
"github.com/baidu/go-lib/log"
)

// BfeListener is used to wrap an underlying TCP listener, which accept connections
// behind a layer4 load balancer (BGW/PROXY)
// behind a layer4 load balancer (PROXY)
type BfeListener struct {
// Listener is the underlying tcp listener
Listener net.Listener
Expand Down Expand Up @@ -76,10 +75,6 @@ func (l *BfeListener) Accept() (net.Conn, error) {
}

switch l.BalancerType {
case bfe_conf.BalancerBgw:
conn = bfe_util.NewBgwConn(conn.(*net.TCPConn))
log.Logger.Debug("BfeListener: accept connection via BGW")

case bfe_conf.BalancerProxy:
conn = bfe_proxy.NewConn(conn, l.ProxyHeaderTimeout, l.ProxyHeaderLimit)
log.Logger.Debug("BfeListener: accept connection via PROXY")
Expand Down
243 changes: 1 addition & 242 deletions bfe_util/get_l4lb_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,37 +15,19 @@
package bfe_util

import (
"encoding/binary"
"errors"
"fmt"
"net"
"sync"
"syscall"
"time"
)

import (
"github.com/baidu/go-lib/log"
)

import (
"github.com/baidu/bfe/bfe_tls"
)

const (
TCP_OPT_CIP_ANY = 230 // get cip from tcp option
TCP_OPT_VIP_ANY = 229 // get vip from tcp option
)

var (
ErrAddressFormat = errors.New("address format error")
)

// GetVipPort return vip and port for given conn
func GetVipPort(conn net.Conn) (net.IP, int, error) {
// get underlying bfe conn, the given net.Conn may be wired like:
// - TLS Connection (optional)
// - BFE Connection (BGW/PROXY, optional)
// - BFE Connection (PROXY, optional)
// - TCP Connection
if tc, ok := conn.(*bfe_tls.Conn); ok {
conn = tc.GetNetConn()
Expand All @@ -71,226 +53,3 @@ func GetVip(conn net.Conn) net.IP {
}
return vip
}

// getVipPortViaBGW gets vip/port from tcp conn via BGW
func getVipPortViaBGW(conn net.Conn) (net.IP, int, error) {
// get conn fd
f, err := GetConnFile(conn)
if err != nil {
return nil, 0, err
}
defer f.Close()
fd := int(f.Fd())

// get vip/port
rawAddr, err := GetsockoptMutiByte(fd, syscall.IPPROTO_TCP, TCP_OPT_VIP_ANY)
if err != nil {
log.Logger.Debug("GetsockoptMutiByte() fail: TCP_OPT_VIP_ANY: %v", err)
return nil, 0, err
}
log.Logger.Debug("getVipPortViaBGW(): VIP raw : %v", rawAddr)

// parse vip/port
return parseSockAddr(rawAddr)
}

// getCipPortViaBGW gets cip/port from tcp conn via BGW
func getCipPortViaBGW(conn net.Conn) (net.IP, int, error) {
// get conn fd
f, err := GetConnFile(conn)
if err != nil {
return nil, 0, err
}
defer f.Close()
fd := int(f.Fd())

// get cip/port
rawAddr, err := GetsockoptMutiByte(fd, syscall.IPPROTO_TCP, TCP_OPT_CIP_ANY)
if err != nil {
log.Logger.Debug("GetsockoptMutiByte fail: TCP_OPT_CIP_ANY: %v", err)
return nil, 0, err
}
log.Logger.Debug("getCipPortViaBGW(): CIP raw : %v", rawAddr)

// parse cip/port
return parseSockAddr(rawAddr)
}

// parseSockAddr parses addr from data with format sockaddr_in/sockaddr_in6
//
// Note: Address format of sockaddr_in:
// struct sockaddr_in {
// sa_family_t sin_family; /* address family: AF_INET */
// in_port_t sin_port; /* port in network byte order */
// struct in_addr sin_addr; /* internet address */
// };
// struct in_addr {
// uint32_t s_addr; /* address in network byte order */
// };
//
// Note: Address format of sockaddr_in6:
// struct sockaddr_in6 {
// sa_family_t sin6_family; /* AF_INET6 */
// in_port_t sin6_port; /* port number */
// uint32_t sin6_flowinfo; /* IPv6 flow information */
// struct in6_addr sin6_addr; /* IPv6 address */
// uint32_t sin6_scope_id; /* Scope ID (new in 2.4) */
// };
// struct in6_addr {
// unsigned char s6_addr[16]; /* IPv6 address */
// };
//
func parseSockAddr(rawAddr []byte) (net.IP, int, error) {
family := NativeUint16(rawAddr[0:2])

// parse ip
var ip net.IP
switch family {
case syscall.AF_INET:
ip = net.IPv4(rawAddr[4], rawAddr[5], rawAddr[6], rawAddr[7]).To4()
case syscall.AF_INET6:
ip = net.IP(rawAddr[8:24]).To16()
default:
return nil, 0, ErrAddressFormat
}
if ip == nil {
return nil, 0, ErrAddressFormat
}

// parse port
port := binary.BigEndian.Uint16(rawAddr[2:4])

return ip, int(port), nil
}

var _ AddressFetcher = new(BgwConn)

// BgwConn is used to wrap an underlying tcp connection which
// may be speaking the bgw Protocol. If it is, the RemoteAddr() will
// return the address of the client.
type BgwConn struct {
conn *net.TCPConn

// srcAddr is address of real client
// Note: srcAddr is different from conn.RemoteAddr() under BGW64
srcAddr *net.TCPAddr

// dstAddr is address of virtual server
dstAddr *net.TCPAddr
once sync.Once
}

// NewBgwConn is used to wrap a net.TCPConn via BGW
func NewBgwConn(conn *net.TCPConn) *BgwConn {
bConn := &BgwConn{
conn: conn,
}
return bConn
}

// Read reads data from the connection.
func (c *BgwConn) Read(b []byte) (int, error) {
return c.conn.Read(b)
}

// Write writes data to the connection.
func (c *BgwConn) Write(b []byte) (int, error) {
return c.conn.Write(b)
}

// Close closes the connection.
func (c *BgwConn) Close() error {
return c.conn.Close()
}

func (c *BgwConn) CloseWrite() error {
return c.conn.CloseWrite()
}

// LocalAddr returns the local network address.
func (c *BgwConn) LocalAddr() net.Addr {
return c.conn.LocalAddr()
}

// RemoteAddr returns the address of the client if the bgw
// protocol is being used, otherwise just returns the address of
// the socket peer.
func (c *BgwConn) RemoteAddr() net.Addr {
c.checkTtmInfoOnce()
if c.srcAddr != nil {
return c.srcAddr
}
return c.conn.RemoteAddr()
}

// VirtualAddr returns the visited address by client
func (c *BgwConn) VirtualAddr() net.Addr {
c.checkTtmInfoOnce()
if c.dstAddr != nil {
return c.dstAddr
}
return nil
}

// BalancerAddr returns the address of balancer
func (c *BgwConn) BalancerAddr() net.Addr {
// Note: Not implement, just ignore
return nil
}

// GetNetConn returns the underlying connection
func (c *BgwConn) GetNetConn() net.Conn {
return c.conn
}

// SetDeadline implements the Conn.SetDeadline method
func (c *BgwConn) SetDeadline(t time.Time) error {
return c.conn.SetDeadline(t)
}

// SetReadDeadline implements the Conn.SetReadDeadline method
func (c *BgwConn) SetReadDeadline(t time.Time) error {
return c.conn.SetReadDeadline(t)
}

// SetWriteDeadline implements the Conn.SetWriteDeadline method
func (c *BgwConn) SetWriteDeadline(t time.Time) error {
return c.conn.SetWriteDeadline(t)
}

func (c *BgwConn) checkTtmInfoOnce() {
c.once.Do(func() {
c.checkTtmInfo()
})
}

func (c *BgwConn) checkTtmInfo() {
c.initSrcAddr()
c.initDstAddr()
}

func (c *BgwConn) initSrcAddr() {
cip, cport, err := getCipPortViaBGW(c)
if err != nil {
log.Logger.Debug("BgwConn getCipPortViaBGW failed, err:%s", err.Error())
return
}

c.srcAddr = &net.TCPAddr{
IP: cip,
Port: cport,
}
}

func (c *BgwConn) initDstAddr() {
vip, vport, err := getVipPortViaBGW(c)
if err != nil {
log.Logger.Debug("BgwConn getVipPortViaBGW failed, err:%s", err.Error())
return
}

c.dstAddr = &net.TCPAddr{
IP: vip,
Port: vport,
}
}
2 changes: 1 addition & 1 deletion conf/bfe.conf
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ MonitorPort = 8421
# max number of CPUs to use (0 to use all CPUs)
MaxCpus = 0

# type of layer-4 load balancer (PROXY/BGW/NONE), default NONE
# type of layer-4 load balancer (PROXY/NONE), default NONE
Layer4LoadBalancer = ""

# tls handshake timeout, in seconds
Expand Down
5 changes: 2 additions & 3 deletions docs/en_us/configuration/bfe.conf.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ bfe.conf is the core configuration file of BFE.
| Basic.HttpsPort | Integer<br>Listen port for HTTPS<br>Default 8443 |
| Basic.MonitorPort | Integer<br>Listen port for monitor<br>Default 8421 |
| Basic.MaxCpus | Integer<br>Max number of CPUs to use (0 to use all CPUs)<br>Default 0 |
| Basic.Layer4LoadBalancer | String<br>Type of layer-4 load balancer (PROXY/BGW/NONE)<br>Default NONE |
| Basic.Layer4LoadBalancer | String<br>Type of layer-4 load balancer (PROXY/NONE)<br>Default NONE |
| Basic.TlsHandshakeTimeout | Integer<br>TLS handshake timeout, in seconds<br>Default 30 |
| Basic.ClientReadTimeout | Integer<br>Read timeout of communicating with http client, in seconds<br>Default 60 |
| Basic.ClientWriteTimeout | Integer<br>Write timeout of communicating with http client, in seconds<br>Default 60 |
Expand Down Expand Up @@ -70,12 +70,11 @@ MonitorPort = 8421
# max number of CPUs to use (0 to use all CPUs)
MaxCpus = 0
# type of layer-4 load balancer (PROXY/BGW/NONE)
# type of layer-4 load balancer (PROXY/NONE)
#
# Note:
# - PROXY: layer-4 balancer talking the proxy protocol
# eg. F5 BigIP/Citrix ADC
# - BGW: Baidu GateWay
# - NONE: layer-4 balancer disabled
Layer4LoadBalancer = ""
Expand Down
2 changes: 1 addition & 1 deletion docs/en_us/installation/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@
| ---------- | ------------------ |
| Linux OS | Support<br>*Recommended development and deployment system* |
| Mac OS | Support |
| Windows OS | Support<br>*Not supported to obtain VIP/CIP when configuring layer 4 load balancing as BGW |
| Windows OS | Support<br> |
5 changes: 2 additions & 3 deletions docs/zh_cn/configuration/bfe.conf.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ bfe.conf是BFE的核心配置
| Server.HttpsPort | Integer<br>HTTPS(TLS)监听端口<br>默认值8443 |
| Server.MonitorPort | Integer<br>Monitor监听端口<br>默认值8421 |
| Server.MaxCpus | Integer<br>最大使用CPU核数; 0代表使用所有CPU核<br>默认值0 |
| Server.Layer4LoadBalancer | String<br>四层负载均衡器类型(PROXY/BGW/NONE)<br>默认值NONE |
| Server.Layer4LoadBalancer | String<br>四层负载均衡器类型(PROXY/NONE)<br>默认值NONE |
| Server.TlsHandshakeTimeout | Integer<br>TLS握手超时时间,单位为秒<br>默认值30 |
| Server.ClientReadTimeout | Integer<br>读客户端超时时间,单位为秒<br>默认值60 |
| Server.ClientWriteTimeout | Integer<br>写客户端超时时间,单位为秒<br>默认值60 |
Expand Down Expand Up @@ -69,12 +69,11 @@ MonitorPort = 8421
# max number of CPUs to use (0 to use all CPUs)
MaxCpus = 0
# type of layer-4 load balancer (PROXY/BGW/NONE)
# type of layer-4 load balancer (PROXY/NONE)
#
# Note:
# - PROXY: layer-4 balancer talking the proxy protocol
# eg. F5 BigIP/Citrix ADC
# - BGW: Baidu GateWay
# - NONE: layer-4 balancer disabled
Layer4LoadBalancer = ""
Expand Down
2 changes: 1 addition & 1 deletion docs/zh_cn/installation/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@
| ---------- | -------------------------------------------------- |
| Linux OS | 支持<br>*建议的开发及部署环境* |
| Mac OS | 支持 |
| Windows OS | 支持<br>*配置四层负载均衡为BGW时,不支持获取VIP/CIP* |
| Windows OS | 支持<br> |

0 comments on commit 2edd981

Please sign in to comment.