| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- package utp
- /*
- #include "utp.h"
- */
- import "C"
- import (
- "net"
- "strconv"
- "syscall"
- "unsafe"
- "github.com/anacrolix/missinggo/inproc"
- )
- func toSockaddrInet(ip net.IP, port int, zone string) (rsa syscall.RawSockaddrAny, len C.socklen_t) {
- if ip4 := ip.To4(); ip4 != nil && zone == "" {
- rsa4 := (*syscall.RawSockaddrInet4)(unsafe.Pointer(&rsa))
- rsa4.Family = syscall.AF_INET
- rsa4.Port = uint16(port)
- if n := copy(rsa4.Addr[:], ip4); n != 4 {
- panic(n)
- }
- len = C.socklen_t(unsafe.Sizeof(*rsa4))
- return
- }
- rsa6 := (*syscall.RawSockaddrInet6)(unsafe.Pointer(&rsa))
- rsa6.Family = syscall.AF_INET6
- rsa6.Scope_id = zoneToScopeId(zone)
- rsa6.Port = uint16(port)
- if ip != nil {
- if n := copy(rsa6.Addr[:], ip); n != 16 {
- panic(n)
- }
- }
- len = C.socklen_t(unsafe.Sizeof(*rsa6))
- return
- }
- func zoneToScopeId(zone string) uint32 {
- if zone == "" {
- return 0
- }
- if ifi, err := net.InterfaceByName(zone); err == nil {
- return uint32(ifi.Index)
- }
- ui64, _ := strconv.ParseUint(zone, 10, 32)
- return uint32(ui64)
- }
- func structSockaddrToUDPAddr(sa *C.struct_sockaddr, udp *net.UDPAddr) error {
- return anySockaddrToUdp((*syscall.RawSockaddrAny)(unsafe.Pointer(sa)), udp)
- }
- func anySockaddrToUdp(rsa *syscall.RawSockaddrAny, udp *net.UDPAddr) error {
- switch rsa.Addr.Family {
- case syscall.AF_INET:
- sa := (*syscall.RawSockaddrInet4)(unsafe.Pointer(rsa))
- udp.Port = int(sa.Port)
- udp.IP = append(udp.IP[:0], sa.Addr[:]...)
- return nil
- case syscall.AF_INET6:
- sa := (*syscall.RawSockaddrInet6)(unsafe.Pointer(rsa))
- udp.Port = int(sa.Port)
- udp.IP = append(udp.IP[:0], sa.Addr[:]...)
- return nil
- default:
- return syscall.EAFNOSUPPORT
- }
- }
- func sockaddrToUDP(sa syscall.Sockaddr) net.Addr {
- switch sa := sa.(type) {
- case *syscall.SockaddrInet4:
- return &net.UDPAddr{IP: sa.Addr[0:], Port: sa.Port}
- case *syscall.SockaddrInet6:
- return &net.UDPAddr{IP: sa.Addr[0:], Port: sa.Port /*Zone: zoneToString(int(sa.ZoneId))*/}
- }
- return nil
- }
- func netAddrToLibSockaddr(na net.Addr) (rsa syscall.RawSockaddrAny, len C.socklen_t) {
- switch v := na.(type) {
- case *net.UDPAddr:
- return toSockaddrInet(v.IP, v.Port, v.Zone)
- case inproc.Addr:
- rsa6 := (*syscall.RawSockaddrInet6)(unsafe.Pointer(&rsa))
- rsa6.Port = uint16(v.Port)
- len = C.socklen_t(unsafe.Sizeof(rsa))
- return
- default:
- panic(na)
- }
- }
|