gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

net.go (8330B)


      1 // Copyright The OpenTelemetry 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 package internal // import "go.opentelemetry.io/otel/semconv/internal/v2"
     16 
     17 import (
     18 	"net"
     19 	"strconv"
     20 	"strings"
     21 
     22 	"go.opentelemetry.io/otel/attribute"
     23 )
     24 
     25 // NetConv are the network semantic convention attributes defined for a version
     26 // of the OpenTelemetry specification.
     27 type NetConv struct {
     28 	NetHostNameKey     attribute.Key
     29 	NetHostPortKey     attribute.Key
     30 	NetPeerNameKey     attribute.Key
     31 	NetPeerPortKey     attribute.Key
     32 	NetSockFamilyKey   attribute.Key
     33 	NetSockPeerAddrKey attribute.Key
     34 	NetSockPeerPortKey attribute.Key
     35 	NetSockHostAddrKey attribute.Key
     36 	NetSockHostPortKey attribute.Key
     37 	NetTransportOther  attribute.KeyValue
     38 	NetTransportTCP    attribute.KeyValue
     39 	NetTransportUDP    attribute.KeyValue
     40 	NetTransportInProc attribute.KeyValue
     41 }
     42 
     43 func (c *NetConv) Transport(network string) attribute.KeyValue {
     44 	switch network {
     45 	case "tcp", "tcp4", "tcp6":
     46 		return c.NetTransportTCP
     47 	case "udp", "udp4", "udp6":
     48 		return c.NetTransportUDP
     49 	case "unix", "unixgram", "unixpacket":
     50 		return c.NetTransportInProc
     51 	default:
     52 		// "ip:*", "ip4:*", and "ip6:*" all are considered other.
     53 		return c.NetTransportOther
     54 	}
     55 }
     56 
     57 // Host returns attributes for a network host address.
     58 func (c *NetConv) Host(address string) []attribute.KeyValue {
     59 	h, p := splitHostPort(address)
     60 	var n int
     61 	if h != "" {
     62 		n++
     63 		if p > 0 {
     64 			n++
     65 		}
     66 	}
     67 
     68 	if n == 0 {
     69 		return nil
     70 	}
     71 
     72 	attrs := make([]attribute.KeyValue, 0, n)
     73 	attrs = append(attrs, c.HostName(h))
     74 	if p > 0 {
     75 		attrs = append(attrs, c.HostPort(int(p)))
     76 	}
     77 	return attrs
     78 }
     79 
     80 // Server returns attributes for a network listener listening at address. See
     81 // net.Listen for information about acceptable address values, address should
     82 // be the same as the one used to create ln. If ln is nil, only network host
     83 // attributes will be returned that describe address. Otherwise, the socket
     84 // level information about ln will also be included.
     85 func (c *NetConv) Server(address string, ln net.Listener) []attribute.KeyValue {
     86 	if ln == nil {
     87 		return c.Host(address)
     88 	}
     89 
     90 	lAddr := ln.Addr()
     91 	if lAddr == nil {
     92 		return c.Host(address)
     93 	}
     94 
     95 	hostName, hostPort := splitHostPort(address)
     96 	sockHostAddr, sockHostPort := splitHostPort(lAddr.String())
     97 	network := lAddr.Network()
     98 	sockFamily := family(network, sockHostAddr)
     99 
    100 	n := nonZeroStr(hostName, network, sockHostAddr, sockFamily)
    101 	n += positiveInt(hostPort, sockHostPort)
    102 	attr := make([]attribute.KeyValue, 0, n)
    103 	if hostName != "" {
    104 		attr = append(attr, c.HostName(hostName))
    105 		if hostPort > 0 {
    106 			// Only if net.host.name is set should net.host.port be.
    107 			attr = append(attr, c.HostPort(hostPort))
    108 		}
    109 	}
    110 	if network != "" {
    111 		attr = append(attr, c.Transport(network))
    112 	}
    113 	if sockFamily != "" {
    114 		attr = append(attr, c.NetSockFamilyKey.String(sockFamily))
    115 	}
    116 	if sockHostAddr != "" {
    117 		attr = append(attr, c.NetSockHostAddrKey.String(sockHostAddr))
    118 		if sockHostPort > 0 {
    119 			// Only if net.sock.host.addr is set should net.sock.host.port be.
    120 			attr = append(attr, c.NetSockHostPortKey.Int(sockHostPort))
    121 		}
    122 	}
    123 	return attr
    124 }
    125 
    126 func (c *NetConv) HostName(name string) attribute.KeyValue {
    127 	return c.NetHostNameKey.String(name)
    128 }
    129 
    130 func (c *NetConv) HostPort(port int) attribute.KeyValue {
    131 	return c.NetHostPortKey.Int(port)
    132 }
    133 
    134 // Client returns attributes for a client network connection to address. See
    135 // net.Dial for information about acceptable address values, address should be
    136 // the same as the one used to create conn. If conn is nil, only network peer
    137 // attributes will be returned that describe address. Otherwise, the socket
    138 // level information about conn will also be included.
    139 func (c *NetConv) Client(address string, conn net.Conn) []attribute.KeyValue {
    140 	if conn == nil {
    141 		return c.Peer(address)
    142 	}
    143 
    144 	lAddr, rAddr := conn.LocalAddr(), conn.RemoteAddr()
    145 
    146 	var network string
    147 	switch {
    148 	case lAddr != nil:
    149 		network = lAddr.Network()
    150 	case rAddr != nil:
    151 		network = rAddr.Network()
    152 	default:
    153 		return c.Peer(address)
    154 	}
    155 
    156 	peerName, peerPort := splitHostPort(address)
    157 	var (
    158 		sockFamily   string
    159 		sockPeerAddr string
    160 		sockPeerPort int
    161 		sockHostAddr string
    162 		sockHostPort int
    163 	)
    164 
    165 	if lAddr != nil {
    166 		sockHostAddr, sockHostPort = splitHostPort(lAddr.String())
    167 	}
    168 
    169 	if rAddr != nil {
    170 		sockPeerAddr, sockPeerPort = splitHostPort(rAddr.String())
    171 	}
    172 
    173 	switch {
    174 	case sockHostAddr != "":
    175 		sockFamily = family(network, sockHostAddr)
    176 	case sockPeerAddr != "":
    177 		sockFamily = family(network, sockPeerAddr)
    178 	}
    179 
    180 	n := nonZeroStr(peerName, network, sockPeerAddr, sockHostAddr, sockFamily)
    181 	n += positiveInt(peerPort, sockPeerPort, sockHostPort)
    182 	attr := make([]attribute.KeyValue, 0, n)
    183 	if peerName != "" {
    184 		attr = append(attr, c.PeerName(peerName))
    185 		if peerPort > 0 {
    186 			// Only if net.peer.name is set should net.peer.port be.
    187 			attr = append(attr, c.PeerPort(peerPort))
    188 		}
    189 	}
    190 	if network != "" {
    191 		attr = append(attr, c.Transport(network))
    192 	}
    193 	if sockFamily != "" {
    194 		attr = append(attr, c.NetSockFamilyKey.String(sockFamily))
    195 	}
    196 	if sockPeerAddr != "" {
    197 		attr = append(attr, c.NetSockPeerAddrKey.String(sockPeerAddr))
    198 		if sockPeerPort > 0 {
    199 			// Only if net.sock.peer.addr is set should net.sock.peer.port be.
    200 			attr = append(attr, c.NetSockPeerPortKey.Int(sockPeerPort))
    201 		}
    202 	}
    203 	if sockHostAddr != "" {
    204 		attr = append(attr, c.NetSockHostAddrKey.String(sockHostAddr))
    205 		if sockHostPort > 0 {
    206 			// Only if net.sock.host.addr is set should net.sock.host.port be.
    207 			attr = append(attr, c.NetSockHostPortKey.Int(sockHostPort))
    208 		}
    209 	}
    210 	return attr
    211 }
    212 
    213 func family(network, address string) string {
    214 	switch network {
    215 	case "unix", "unixgram", "unixpacket":
    216 		return "unix"
    217 	default:
    218 		if ip := net.ParseIP(address); ip != nil {
    219 			if ip.To4() == nil {
    220 				return "inet6"
    221 			}
    222 			return "inet"
    223 		}
    224 	}
    225 	return ""
    226 }
    227 
    228 func nonZeroStr(strs ...string) int {
    229 	var n int
    230 	for _, str := range strs {
    231 		if str != "" {
    232 			n++
    233 		}
    234 	}
    235 	return n
    236 }
    237 
    238 func positiveInt(ints ...int) int {
    239 	var n int
    240 	for _, i := range ints {
    241 		if i > 0 {
    242 			n++
    243 		}
    244 	}
    245 	return n
    246 }
    247 
    248 // Peer returns attributes for a network peer address.
    249 func (c *NetConv) Peer(address string) []attribute.KeyValue {
    250 	h, p := splitHostPort(address)
    251 	var n int
    252 	if h != "" {
    253 		n++
    254 		if p > 0 {
    255 			n++
    256 		}
    257 	}
    258 
    259 	if n == 0 {
    260 		return nil
    261 	}
    262 
    263 	attrs := make([]attribute.KeyValue, 0, n)
    264 	attrs = append(attrs, c.PeerName(h))
    265 	if p > 0 {
    266 		attrs = append(attrs, c.PeerPort(int(p)))
    267 	}
    268 	return attrs
    269 }
    270 
    271 func (c *NetConv) PeerName(name string) attribute.KeyValue {
    272 	return c.NetPeerNameKey.String(name)
    273 }
    274 
    275 func (c *NetConv) PeerPort(port int) attribute.KeyValue {
    276 	return c.NetPeerPortKey.Int(port)
    277 }
    278 
    279 func (c *NetConv) SockPeerAddr(addr string) attribute.KeyValue {
    280 	return c.NetSockPeerAddrKey.String(addr)
    281 }
    282 
    283 func (c *NetConv) SockPeerPort(port int) attribute.KeyValue {
    284 	return c.NetSockPeerPortKey.Int(port)
    285 }
    286 
    287 // splitHostPort splits a network address hostport of the form "host",
    288 // "host%zone", "[host]", "[host%zone], "host:port", "host%zone:port",
    289 // "[host]:port", "[host%zone]:port", or ":port" into host or host%zone and
    290 // port.
    291 //
    292 // An empty host is returned if it is not provided or unparsable. A negative
    293 // port is returned if it is not provided or unparsable.
    294 func splitHostPort(hostport string) (host string, port int) {
    295 	port = -1
    296 
    297 	if strings.HasPrefix(hostport, "[") {
    298 		addrEnd := strings.LastIndex(hostport, "]")
    299 		if addrEnd < 0 {
    300 			// Invalid hostport.
    301 			return
    302 		}
    303 		if i := strings.LastIndex(hostport[addrEnd:], ":"); i < 0 {
    304 			host = hostport[1:addrEnd]
    305 			return
    306 		}
    307 	} else {
    308 		if i := strings.LastIndex(hostport, ":"); i < 0 {
    309 			host = hostport
    310 			return
    311 		}
    312 	}
    313 
    314 	host, pStr, err := net.SplitHostPort(hostport)
    315 	if err != nil {
    316 		return
    317 	}
    318 
    319 	p, err := strconv.ParseUint(pStr, 10, 16)
    320 	if err != nil {
    321 		return
    322 	}
    323 	return host, int(p)
    324 }