status-go/vendor/github.com/marten-seemann/tcp/conn_linux.go

45 lines
1.2 KiB
Go

// Copyright 2016 Mikio Hara. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package tcp
import (
"encoding/binary"
"net"
"unsafe"
)
func (c *Conn) originalDst(la, _ *net.TCPAddr) (net.Addr, error) {
var level, name int
var b []byte
if la.IP.To4() != nil {
level = ianaProtocolIP
name = sysSO_ORIGINAL_DST
b = make([]byte, sizeofSockaddrInet)
}
if la.IP.To16() != nil && la.IP.To4() == nil {
level = ianaProtocolIPv6
name = sysIP6T_SO_ORIGINAL_DST
b = make([]byte, sizeofSockaddrInet6)
}
if _, err := c.option(level, name, b); err != nil {
return nil, err
}
od := new(net.TCPAddr)
switch len(b) {
case sizeofSockaddrInet:
sa := (*sockaddrInet)(unsafe.Pointer(&b[0]))
od.IP = make(net.IP, net.IPv4len)
copy(od.IP, sa.Addr[:])
od.Port = int(binary.BigEndian.Uint16((*[2]byte)(unsafe.Pointer(&sa.Port))[:]))
case sizeofSockaddrInet6:
sa := (*sockaddrInet6)(unsafe.Pointer(&b[0]))
od.IP = make(net.IP, net.IPv6len)
copy(od.IP, sa.Addr[:])
od.Port = int(binary.BigEndian.Uint16((*[2]byte)(unsafe.Pointer(&sa.Port))[:]))
od.Zone = zoneCache.name(int(sa.Scope_id))
}
return od, nil
}