istio

Форк
0
107 строк · 3.0 Кб
1
// Copyright Istio Authors
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
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
16
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
17

18
package validation
19

20
import (
21
	"errors"
22
	"fmt"
23
	"net"
24
	"syscall"
25

26
	"golang.org/x/sys/unix"
27

28
	"istio.io/istio/pkg/log"
29
	"istio.io/istio/tools/istio-iptables/pkg/constants"
30
)
31

32
// Recover the original address from redirect socket. Supposed to work for tcp over ipv4 and ipv6.
33
func GetOriginalDestination(conn net.Conn) (daddr net.IP, dport uint16, err error) {
34
	// obtain os fd from Conn
35
	tcp, ok := conn.(*net.TCPConn)
36
	if !ok {
37
		err = errors.New("socket is not tcp")
38
		return
39
	}
40
	file, err := tcp.File()
41
	if err != nil {
42
		return
43
	}
44
	defer file.Close()
45
	fd := file.Fd()
46

47
	// Detect underlying ip is v4 or v6
48
	ip := conn.RemoteAddr().(*net.TCPAddr).IP
49
	isIpv4 := false
50
	if ip.To4() != nil {
51
		isIpv4 = true
52
	} else if ip.To16() != nil {
53
		isIpv4 = false
54
	} else {
55
		err = fmt.Errorf("neither ipv6 nor ipv4 original addr: %s", ip)
56
		return
57
	}
58

59
	// golang doesn't provide a struct sockaddr_storage
60
	// IPv6MTUInfo is chosen because
61
	// 1. it is no smaller than sockaddr_storage,
62
	// 2. it is provide the port field value
63
	var addr *unix.IPv6MTUInfo
64
	if isIpv4 {
65
		addr, err = unix.GetsockoptIPv6MTUInfo(
66
			int(fd),
67
			unix.IPPROTO_IP,
68
			constants.SoOriginalDst)
69
		if err != nil {
70
			log.Errorf("Error ipv4 getsockopt: %v", err)
71
			return
72
		}
73
		// See struct sockaddr_in
74
		daddr = net.IPv4(
75
			addr.Addr.Addr[0], addr.Addr.Addr[1], addr.Addr.Addr[2], addr.Addr.Addr[3])
76
	} else {
77
		addr, err = unix.GetsockoptIPv6MTUInfo(
78
			int(fd), unix.IPPROTO_IPV6,
79
			constants.SoOriginalDst)
80
		if err != nil {
81
			log.Errorf("Error to ipv6 getsockopt: %v", err)
82
			return
83
		}
84
		// See struct sockaddr_in6
85
		daddr = addr.Addr.Addr[:]
86
	}
87
	// See sockaddr_in6 and sockaddr_in
88
	dport = ntohs(addr.Addr.Port)
89

90
	log.Infof("Local addr %s", conn.LocalAddr())
91
	log.Infof("Original addr %s: %d", ip, dport)
92
	return
93
}
94

95
// Setup reuse address to run the validation server more robustly
96
func reuseAddr(network, address string, conn syscall.RawConn) error {
97
	return conn.Control(func(descriptor uintptr) {
98
		err := unix.SetsockoptInt(int(descriptor), unix.SOL_SOCKET, unix.SO_REUSEADDR, 1)
99
		if err != nil {
100
			log.Errorf("Fail to set fd %d SO_REUSEADDR with error %v", descriptor, err)
101
		}
102
		err = unix.SetsockoptInt(int(descriptor), unix.SOL_SOCKET, unix.SO_REUSEPORT, 1)
103
		if err != nil {
104
			log.Errorf("Fail to set fd %d SO_REUSEPORT with error %v", descriptor, err)
105
		}
106
	})
107
}
108

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.