...

Source file src/go.opentelemetry.io/otel/semconv/internal/v2/net.go

Documentation: go.opentelemetry.io/otel/semconv/internal/v2

     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  }
   325  

View as plain text