package tcpip import ( "errors" "fmt" "reflect" "strings" "sync/atomic" ) type Error struct { msg string ignoreStats bool } func (e *Error) String() string { return e.msg } func (e *Error) IgnoreStats() bool { return e.ignoreStats } var ( ErrUnknownProtocol = &Error{msg: "unknown protocol"} ErrUnknownNICID = &Error{msg: "unknown nic id"} ErrUnknownProtocolOption = &Error{msg: "unknown option for protocol"} ErrDuplicateNICID = &Error{msg: "duplicate nic id"} ErrDuplicateAddress = &Error{msg: "duplicate address"} ErrNoRoute = &Error{msg: "no route"} ErrBadLinkEndpoint = &Error{msg: "bad link layer endpoint"} ErrAlreadyBound = &Error{msg: "endpoint already bound", ignoreStats: true} ErrInvalidEndpointState = &Error{msg: "endpoint is in invalid state"} ErrAlreadyConnecting = &Error{msg: "endpoint is already connecting", ignoreStats: true} ErrAlreadyConnected = &Error{msg: "endpoint is already connected", ignoreStats: true} ErrNoPortAvailable = &Error{msg: "no ports are available"} ErrPortInUse = &Error{msg: "port is in use"} ErrBadLocalAddress = &Error{msg: "bad local address"} ErrClosedForSend = &Error{msg: "endpoint is closed for send"} ErrClosedForReceive = &Error{msg: "endpoint is closed for receive"} ErrWouldBlock = &Error{msg: "operation would block", ignoreStats: true} ErrConnectionRefused = &Error{msg: "connection was refused"} ErrTimeout = &Error{msg: "operation timed out"} ErrAborted = &Error{msg: "operation aborted"} ErrConnectStarted = &Error{msg: "connection attempt started", ignoreStats: true} ErrDestinationRequired = &Error{msg: "destination address is required"} ErrNotSupported = &Error{msg: "operation not supported"} ErrQueueSizeNotSupported = &Error{msg: "queue size querying not supported"} ErrNotConnected = &Error{msg: "endpoint not connected"} ErrConnectionReset = &Error{msg: "connection reset by peer"} ErrConnectionAborted = &Error{msg: "connection aborted"} ErrNoSuchFile = &Error{msg: "no such file"} ErrInvalidOptionValue = &Error{msg: "invalid option value specified"} ErrNoLinkAddress = &Error{msg: "no remote link address"} ErrBadAddress = &Error{msg: "bad address"} ErrNetworkUnreachable = &Error{msg: "network is unreachable"} ErrMessageTooLong = &Error{msg: "message too long"} ErrNoBufferSpace = &Error{msg: "no buffer space available"} ) // Errors related to Subnet var ( errSubnetLengthMismatch = errors.New("subnet length of address and mask differ") errSubnetAddressMasked = errors.New("subnet address has bits set outside the mask") ) // Clock 提供当前的时间戳 type Clock interface { NowNanoseconds() int64 NowMonotonic() int64 } // 地址是一个字节切片,转换为表示网络节点地址的字符串。或者,在 unix 端点的情况下,它可能代表一条路径 type Address string type AddressMask string // 传输层的完整地址 type FullAddress struct { NIC NICID // NICID Addr Address // IP Address Port uint16 // transport Port } func (a AddressMask) String() string { return Address(a).String() } type Subnet struct { address Address mask AddressMask } // NewSubnet creates a new Subnet, checking that the address and mask are the same length. func NewSubnet(a Address, m AddressMask) (Subnet, error) { if len(a) != len(m) { return Subnet{}, errSubnetLengthMismatch } for i := 0; i < len(a); i++ { if a[i]&^m[i] != 0 { return Subnet{}, errSubnetAddressMasked } } return Subnet{a, m}, nil } // Contains returns true iff the address is of the same length and matches the // subnet address and mask. func (s *Subnet) Contains(a Address) bool { if len(a) != len(s.address) { return false } for i := 0; i < len(a); i++ { if a[i]&s.mask[i] != s.address[i] { return false } } return true } // ID returns the subnet ID. func (s *Subnet) ID() Address { return s.address } // Bits returns the number of ones (network bits) and zeros (host bits) in the // subnet mask. func (s *Subnet) Bits() (ones int, zeros int) { for _, b := range []byte(s.mask) { for i := uint(0); i < 8; i++ { if b&(1<= 0; j-- { if b&(1< i+2 && j-i > end-start { start, end = i, j } } var b strings.Builder for i := 0; i < len(a); i += 2 { if i == start { b.WriteString("::") i = end if end >= len(a) { break } } else if i > 0 { b.WriteByte(':') } v := uint16(a[i+0])<<8 | uint16(a[i+1]) if v == 0 { b.WriteByte('0') } else { const digits = "0123456789abcdef" for i := uint(3); i < 4; i-- { if v := v >> (i * 4); v != 0 { b.WriteByte(digits[v&0xf]) } } } } return b.String() default: return fmt.Sprintf("%x", []byte(a)) } }