github.com/osrg/gobgp/v3@v3.30.0/pkg/server/util.go (about) 1 // Copyright (C) 2016 Nippon Telegraph and Telephone Corporation. 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 12 // implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 //go:build !windows 16 // +build !windows 17 18 package server 19 20 import ( 21 "net" 22 "strings" 23 "syscall" 24 25 "github.com/eapache/channels" 26 27 "github.com/osrg/gobgp/v3/pkg/packet/bgp" 28 ) 29 30 func cleanInfiniteChannel(ch *channels.InfiniteChannel) { 31 ch.Close() 32 // drain all remaining items 33 for range ch.Out() { 34 } 35 } 36 37 // Returns the binary formatted Administrative Shutdown Communication from the 38 // given string value. 39 func newAdministrativeCommunication(communication string) (data []byte) { 40 if communication == "" { 41 return nil 42 } 43 com := []byte(communication) 44 if len(com) > bgp.BGP_ERROR_ADMINISTRATIVE_COMMUNICATION_MAX { 45 data = []byte{bgp.BGP_ERROR_ADMINISTRATIVE_COMMUNICATION_MAX} 46 data = append(data, com[:bgp.BGP_ERROR_ADMINISTRATIVE_COMMUNICATION_MAX]...) 47 } else { 48 data = []byte{byte(len(com))} 49 data = append(data, com...) 50 } 51 return data 52 } 53 54 // Parses the given NOTIFICATION message data as a binary value and returns 55 // the Administrative Shutdown Communication in string and the rest binary. 56 func decodeAdministrativeCommunication(data []byte) (string, []byte) { 57 if len(data) == 0 { 58 return "", data 59 } 60 communicationLen := int(data[0]) 61 if communicationLen > bgp.BGP_ERROR_ADMINISTRATIVE_COMMUNICATION_MAX { 62 communicationLen = bgp.BGP_ERROR_ADMINISTRATIVE_COMMUNICATION_MAX 63 } 64 if communicationLen > len(data)-1 { 65 communicationLen = len(data) - 1 66 } 67 return string(data[1 : communicationLen+1]), data[communicationLen+1:] 68 } 69 70 func extractFamilyFromTCPConn(conn *net.TCPConn) int { 71 family := syscall.AF_INET 72 if strings.Contains(conn.RemoteAddr().String(), "[") { 73 family = syscall.AF_INET6 74 } 75 return family 76 } 77 78 func setsockOptString(sc syscall.RawConn, level int, opt int, str string) error { 79 var opterr error 80 fn := func(s uintptr) { 81 opterr = syscall.SetsockoptString(int(s), level, opt, str) 82 } 83 err := sc.Control(fn) 84 if opterr == nil { 85 return err 86 } 87 return opterr 88 } 89 90 func setsockOptInt(sc syscall.RawConn, level, name, value int) error { 91 var opterr error 92 fn := func(s uintptr) { 93 opterr = syscall.SetsockoptInt(int(s), level, name, value) 94 } 95 err := sc.Control(fn) 96 if opterr == nil { 97 return err 98 } 99 return opterr 100 } 101 102 func setsockoptIpTtl(sc syscall.RawConn, family int, value int) error { 103 level := syscall.IPPROTO_IP 104 name := syscall.IP_TTL 105 if family == syscall.AF_INET6 { 106 level = syscall.IPPROTO_IPV6 107 name = syscall.IPV6_UNICAST_HOPS 108 } 109 return setsockOptInt(sc, level, name, value) 110 } 111 112 func setsockoptTcpMss(sc syscall.RawConn, family int, value uint16) error { 113 level := syscall.IPPROTO_TCP 114 name := syscall.TCP_MAXSEG 115 return setsockOptInt(sc, level, name, int(value)) 116 }