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