github.com/database64128/shadowsocks-go@v1.10.2-0.20240315062903-143a773533f1/conn/sockaddr_notwindows.go (about)

     1  //go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
     2  
     3  package conn
     4  
     5  import (
     6  	"fmt"
     7  	"net/netip"
     8  	"unsafe"
     9  
    10  	"golang.org/x/sys/unix"
    11  )
    12  
    13  func SockaddrValueToAddrPort(rsa6 unix.RawSockaddrInet6, namelen uint32) (netip.AddrPort, error) {
    14  	p := (*[2]byte)(unsafe.Pointer(&rsa6.Port))
    15  	port := uint16(p[0])<<8 + uint16(p[1])
    16  	var addr netip.Addr
    17  	switch namelen {
    18  	case unix.SizeofSockaddrInet4:
    19  		addr = netip.AddrFrom4(*(*[4]byte)(unsafe.Pointer(&rsa6.Flowinfo)))
    20  	case unix.SizeofSockaddrInet6:
    21  		addr = netip.AddrFrom16(rsa6.Addr)
    22  	default:
    23  		return netip.AddrPort{}, fmt.Errorf("bad sockaddr length: %d", namelen)
    24  	}
    25  	return netip.AddrPortFrom(addr, port), nil
    26  }
    27  
    28  func AddrPortToSockaddr(addrPort netip.AddrPort) (name *byte, namelen uint32) {
    29  	if addrPort.Addr().Is4() {
    30  		rsa4 := AddrPortToSockaddrInet4(addrPort)
    31  		name = (*byte)(unsafe.Pointer(&rsa4))
    32  		namelen = unix.SizeofSockaddrInet4
    33  	} else {
    34  		rsa6 := AddrPortToSockaddrInet6(addrPort)
    35  		name = (*byte)(unsafe.Pointer(&rsa6))
    36  		namelen = unix.SizeofSockaddrInet6
    37  	}
    38  	return
    39  }
    40  
    41  func AddrPortUnmappedToSockaddr(addrPort netip.AddrPort) (name *byte, namelen uint32) {
    42  	if addr := addrPort.Addr(); addr.Is4() || addr.Is4In6() {
    43  		rsa4 := AddrPortToSockaddrInet4(addrPort)
    44  		name = (*byte)(unsafe.Pointer(&rsa4))
    45  		namelen = unix.SizeofSockaddrInet4
    46  	} else {
    47  		rsa6 := AddrPortToSockaddrInet6(addrPort)
    48  		name = (*byte)(unsafe.Pointer(&rsa6))
    49  		namelen = unix.SizeofSockaddrInet6
    50  	}
    51  	return
    52  }
    53  
    54  func SockaddrToAddrPort(name *byte, namelen uint32) (netip.AddrPort, error) {
    55  	switch namelen {
    56  	case unix.SizeofSockaddrInet4:
    57  		rsa4 := (*unix.RawSockaddrInet4)(unsafe.Pointer(name))
    58  		return SockaddrInet4ToAddrPort(rsa4), nil
    59  
    60  	case unix.SizeofSockaddrInet6:
    61  		rsa6 := (*unix.RawSockaddrInet6)(unsafe.Pointer(name))
    62  		return SockaddrInet6ToAddrPort(rsa6), nil
    63  
    64  	default:
    65  		return netip.AddrPort{}, fmt.Errorf("bad sockaddr length: %d", namelen)
    66  	}
    67  }
    68  
    69  func SockaddrInet4ToAddrPort(sa *unix.RawSockaddrInet4) netip.AddrPort {
    70  	portp := (*[2]byte)(unsafe.Pointer(&sa.Port))
    71  	port := uint16(portp[0])<<8 + uint16(portp[1])
    72  	ip := netip.AddrFrom4(sa.Addr)
    73  	return netip.AddrPortFrom(ip, port)
    74  }
    75  
    76  func SockaddrInet6ToAddrPort(sa *unix.RawSockaddrInet6) netip.AddrPort {
    77  	portp := (*[2]byte)(unsafe.Pointer(&sa.Port))
    78  	port := uint16(portp[0])<<8 + uint16(portp[1])
    79  	ip := netip.AddrFrom16(sa.Addr)
    80  	return netip.AddrPortFrom(ip, port)
    81  }