Commit 6a9148fa authored by tavit ohanian's avatar tavit ohanian

reference basis

parents 76fd27fa bc3977c2
Pipeline #488 failed with stages
in 0 seconds
# File managed by web3-bot. DO NOT EDIT.
# See https://github.com/protocol/.github/ for details.
# Automatically merge pull requests opened by web3-bot, as soon as (and only if) all tests pass.
# This reduces the friction associated with updating with our workflows.
on: [ pull_request ]
name: Automerge
jobs:
automerge-check:
if: github.event.pull_request.user.login == 'web3-bot'
runs-on: ubuntu-latest
outputs:
status: ${{ steps.should-automerge.outputs.status }}
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Check if we should automerge
id: should-automerge
run: |
for commit in $(git rev-list --first-parent origin/${{ github.event.pull_request.base.ref }}..${{ github.event.pull_request.head.sha }}); do
committer=$(git show --format=$'%ce' -s $commit)
echo "Committer: $committer"
if [[ "$committer" != "web3-bot@users.noreply.github.com" ]]; then
echo "Commit $commit wasn't committed by web3-bot, but by $committer."
echo "::set-output name=status::false"
exit
fi
done
echo "::set-output name=status::true"
automerge:
needs: automerge-check
runs-on: ubuntu-latest
if: ${{ needs.automerge-check.outputs.status == 'true' }}
steps:
- name: Wait on tests
uses: lewagon/wait-on-check-action@bafe56a6863672c681c3cf671f5e10b20abf2eaa # v0.2
with:
ref: ${{ github.event.pull_request.head.sha }}
repo-token: ${{ secrets.GITHUB_TOKEN }}
wait-interval: 10
running-workflow-name: 'automerge' # the name of this job
- name: Merge PR
uses: pascalgn/automerge-action@741c311a47881be9625932b0a0de1b0937aab1ae # v0.13.1
env:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
MERGE_LABELS: ""
MERGE_METHOD: "squash"
MERGE_DELETE_BRANCH: true
# File managed by web3-bot. DO NOT EDIT.
# See https://github.com/protocol/.github/ for details.
on: [push, pull_request]
name: Go Checks
jobs:
unit:
runs-on: ubuntu-latest
name: All
steps:
- uses: actions/checkout@v2
with:
submodules: recursive
- uses: actions/setup-go@v2
with:
go-version: "1.16.x"
- name: Install staticcheck
run: go install honnef.co/go/tools/cmd/staticcheck@434f5f3816b358fe468fa83dcba62d794e7fe04b # 2021.1 (v0.2.0)
- name: Check that go.mod is tidy
uses: protocol/multiple-go-modules@v1.0
with:
run: |
go mod tidy
if [[ -n $(git ls-files --other --exclude-standard --directory -- go.sum) ]]; then
echo "go.sum was added by go mod tidy"
exit 1
fi
git diff --exit-code -- go.sum go.mod
- name: gofmt
if: ${{ success() || failure() }} # run this step even if the previous one failed
run: |
out=$(gofmt -s -l .)
if [[ -n "$out" ]]; then
echo $out | awk '{print "::error file=" $0 ",line=0,col=0::File is not gofmt-ed."}'
exit 1
fi
- name: go vet
if: ${{ success() || failure() }} # run this step even if the previous one failed
uses: protocol/multiple-go-modules@v1.0
with:
run: go vet ./...
- name: staticcheck
if: ${{ success() || failure() }} # run this step even if the previous one failed
uses: protocol/multiple-go-modules@v1.0
with:
run: |
set -o pipefail
staticcheck ./... | sed -e 's@\(.*\)\.go@./\1.go@g'
# File managed by web3-bot. DO NOT EDIT.
# See https://github.com/protocol/.github/ for details.
on: [push, pull_request]
name: Go Test
jobs:
unit:
strategy:
fail-fast: false
matrix:
os: [ "ubuntu", "windows", "macos" ]
go: [ "1.15.x", "1.16.x" ]
runs-on: ${{ matrix.os }}-latest
name: ${{ matrix.os}} (go ${{ matrix.go }})
steps:
- uses: actions/checkout@v2
with:
submodules: recursive
- uses: actions/setup-go@v2
with:
go-version: ${{ matrix.go }}
- name: Go information
run: |
go version
go env
- name: Run tests
uses: protocol/multiple-go-modules@v1.0
with:
run: go test -v -coverprofile coverage.txt ./...
- name: Run tests (32 bit)
if: ${{ matrix.os != 'macos' }} # can't run 32 bit tests on OSX.
uses: protocol/multiple-go-modules@v1.0
env:
GOARCH: 386
with:
run: go test -v ./...
- name: Run tests with race detector
if: ${{ matrix.os == 'ubuntu' }} # speed things up. Windows and OSX VMs are slow
uses: protocol/multiple-go-modules@v1.0
with:
run: go test -v -race ./...
- name: Upload coverage to Codecov
uses: codecov/codecov-action@a1ed4b322b4b38cb846afb5a0ebfa17086917d27 # v1.5.0
with:
file: coverage.txt
env_vars: OS=${{ matrix.os }}, GO=${{ matrix.go }}
Copyright (c) 2012 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# go-sockaddr ## go-sockaddr - `{Raw,}Sockaddr` conversions
dms3 p2p go-sockaddr See https://groups.google.com/d/msg/golang-nuts/B-meiFfkmH0/-TxP1r6zvk8J
\ No newline at end of file This package extracts unexported code from `golang.org/x/unix` to help in converting
between:
```Go
${platform}.Sockaddr
${platform}.RawSockaddrAny
C.struct_sockaddr_any
net.*Addr
```
Godoc:
- sockaddr - http://godoc.org/github.com/libp2p/go-sockaddr
- sockaddr/net - http://godoc.org/github.com/libp2p/go-sockaddr/net
---
The last gx published version of this module was: 1.0.3: QmNzEyX7vjWiqinyLeavcAF1oegav6dZ1aQpAkYvG9m5Ze
module github.com/libp2p/go-sockaddr
require golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e
go 1.15
golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e h1:ZytStCyV048ZqDsWHiYDdoI2Vd4msMcrDECFxS+tL9c=
golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
// package sockaddrnet provides conversions between net.Addr and Sockaddr
package sockaddrnet
import (
"net"
)
// NetAddrAF returns the unix AF_* type for a given net.Addr
// returns AF_UNSPEC if unknown
func NetAddrAF(addr net.Addr) int {
switch addr := addr.(type) {
case *net.IPAddr:
return IPAF(addr.IP)
case *net.TCPAddr:
return IPAF(addr.IP)
case *net.UDPAddr:
return IPAF(addr.IP)
case *net.UnixAddr:
return AF_UNIX
default:
return AF_UNSPEC
}
}
// IPAF returns the unix AF_* type for a given IP address
// returns AF_UNSPEC if unknown
func IPAF(ip net.IP) int {
switch {
case ip.To4() != nil:
return AF_INET
case ip.To16() != nil:
return AF_INET6
default:
return AF_UNSPEC
}
}
// NetAddrIPPROTO returns the unix IPPROTO_* type for a given net.Addr
// returns -1 if protocol unknown
func NetAddrIPPROTO(addr net.Addr) int {
switch addr := addr.(type) {
case *net.IPAddr:
switch {
default:
return IPPROTO_IP
case addr.IP.To4() != nil:
return IPPROTO_IPV4
case addr.IP.To16() != nil:
return IPPROTO_IPV6
}
case *net.TCPAddr:
return IPPROTO_TCP
case *net.UDPAddr:
return IPPROTO_UDP
default:
return -1
}
}
// NetAddrSOCK returns the unix SOCK_* type for a given net.Addr
// returns 0 if type unknown
func NetAddrSOCK(addr net.Addr) int {
switch addr := addr.(type) {
case *net.IPAddr:
return SOCK_DGRAM
case *net.TCPAddr:
return SOCK_STREAM
case *net.UDPAddr:
return SOCK_DGRAM
case *net.UnixAddr:
switch addr.Net {
default:
return 0
case "unix":
return SOCK_STREAM
case "unixgram":
return SOCK_DGRAM
case "unixpacket":
return SOCK_SEQPACKET
}
default:
return 0
}
}
// NetAddrToSockaddr converts a net.Addr to a Sockaddr.
// Returns nil if the input is invalid or conversion is not possible.
func NetAddrToSockaddr(addr net.Addr) Sockaddr {
switch addr := addr.(type) {
case *net.IPAddr:
return IPAddrToSockaddr(addr)
case *net.TCPAddr:
return TCPAddrToSockaddr(addr)
case *net.UDPAddr:
return UDPAddrToSockaddr(addr)
case *net.UnixAddr:
sa, _ := UnixAddrToSockaddr(addr)
return sa
default:
return nil
}
}
// IPAndZoneToSockaddr converts a net.IP (with optional IPv6 Zone) to a Sockaddr
// Returns nil if conversion fails.
func IPAndZoneToSockaddr(ip net.IP, zone string) Sockaddr {
// Unspecified?
if ip == nil {
if zone != "" {
return &SockaddrInet6{ZoneId: uint32(IP6ZoneToInt(zone))}
}
return new(SockaddrInet4)
}
// Valid IPv4?
if ip4 := ip.To4(); ip4 != nil && zone == "" {
var buf [4]byte
copy(buf[:], ip4) // last 4 bytes
return &SockaddrInet4{Addr: buf}
}
// Valid IPv6 address?
if ip6 := ip.To16(); ip6 != nil {
var buf [16]byte
copy(buf[:], ip6)
return &SockaddrInet6{Addr: buf, ZoneId: uint32(IP6ZoneToInt(zone))}
}
return nil
}
// IPAddrToSockaddr converts a net.IPAddr to a Sockaddr.
// Returns nil if conversion fails.
func IPAddrToSockaddr(addr *net.IPAddr) Sockaddr {
return IPAndZoneToSockaddr(addr.IP, addr.Zone)
}
// TCPAddrToSockaddr converts a net.TCPAddr to a Sockaddr.
// Returns nil if conversion fails.
func TCPAddrToSockaddr(addr *net.TCPAddr) Sockaddr {
sa := IPAndZoneToSockaddr(addr.IP, addr.Zone)
switch sa := sa.(type) {
case *SockaddrInet4:
sa.Port = addr.Port
return sa
case *SockaddrInet6:
sa.Port = addr.Port
return sa
default:
return nil
}
}
// UDPAddrToSockaddr converts a net.UDPAddr to a Sockaddr.
// Returns nil if conversion fails.
func UDPAddrToSockaddr(addr *net.UDPAddr) Sockaddr {
sa := IPAndZoneToSockaddr(addr.IP, addr.Zone)
switch sa := sa.(type) {
case *SockaddrInet4:
sa.Port = addr.Port
return sa
case *SockaddrInet6:
sa.Port = addr.Port
return sa
default:
return nil
}
}
// UnixAddrToSockaddr converts a net.UnixAddr to a Sockaddr, and returns
// the type (unix.SOCK_STREAM, unix.SOCK_DGRAM, unix.SOCK_SEQPACKET)
// Returns (nil, 0) if conversion fails.
func UnixAddrToSockaddr(addr *net.UnixAddr) (Sockaddr, int) {
t := 0
switch addr.Net {
case "unix":
t = SOCK_STREAM
case "unixgram":
t = SOCK_DGRAM
case "unixpacket":
t = SOCK_SEQPACKET
default:
return nil, 0
}
return &SockaddrUnix{Name: addr.Name}, t
}
// SockaddrToIPAndZone converts a Sockaddr to a net.IP (with optional IPv6 Zone)
// Returns nil if conversion fails.
func SockaddrToIPAndZone(sa Sockaddr) (net.IP, string) {
switch sa := sa.(type) {
case *SockaddrInet4:
ip := make([]byte, 16)
// V4InV6Prefix
ip[10] = 0xff
ip[11] = 0xff
copy(ip[12:16], sa.Addr[:])
return ip, ""
case *SockaddrInet6:
ip := make([]byte, 16)
copy(ip, sa.Addr[:])
return ip, IP6ZoneToString(int(sa.ZoneId))
}
return nil, ""
}
// SockaddrToIPAddr converts a Sockaddr to a net.IPAddr
// Returns nil if conversion fails.
func SockaddrToIPAddr(sa Sockaddr) *net.IPAddr {
ip, zone := SockaddrToIPAndZone(sa)
switch sa.(type) {
case *SockaddrInet4:
return &net.IPAddr{IP: ip}
case *SockaddrInet6:
return &net.IPAddr{IP: ip, Zone: zone}
}
return nil
}
// SockaddrToTCPAddr converts a Sockaddr to a net.TCPAddr
// Returns nil if conversion fails.
func SockaddrToTCPAddr(sa Sockaddr) *net.TCPAddr {
ip, zone := SockaddrToIPAndZone(sa)
switch sa := sa.(type) {
case *SockaddrInet4:
return &net.TCPAddr{IP: ip, Port: sa.Port}
case *SockaddrInet6:
return &net.TCPAddr{IP: ip, Port: sa.Port, Zone: zone}
}
return nil
}
// SockaddrToUDPAddr converts a Sockaddr to a net.UDPAddr
// Returns nil if conversion fails.
func SockaddrToUDPAddr(sa Sockaddr) *net.UDPAddr {
ip, zone := SockaddrToIPAndZone(sa)
switch sa := sa.(type) {
case *SockaddrInet4:
return &net.UDPAddr{IP: ip, Port: sa.Port}
case *SockaddrInet6:
return &net.UDPAddr{IP: ip, Port: sa.Port, Zone: zone}
}
return nil
}
// from: go/src/pkg/net/unixsock_posix.go
// SockaddrToUnixAddr converts a Sockaddr to a net.UnixAddr
// Returns nil if conversion fails.
func SockaddrToUnixAddr(sa Sockaddr) *net.UnixAddr {
if s, ok := sa.(*SockaddrUnix); ok {
return &net.UnixAddr{Name: s.Name, Net: "unix"}
}
return nil
}
// SockaddrToUnixgramAddr converts a Sockaddr to a net.UnixAddr
// Returns nil if conversion fails.
func SockaddrToUnixgramAddr(sa Sockaddr) *net.UnixAddr {
if s, ok := sa.(*SockaddrUnix); ok {
return &net.UnixAddr{Name: s.Name, Net: "unixgram"}
}
return nil
}
// SockaddrToUnixpacketAddr converts a Sockaddr to a net.UnixAddr
// Returns nil if conversion fails.
func SockaddrToUnixpacketAddr(sa Sockaddr) *net.UnixAddr {
if s, ok := sa.(*SockaddrUnix); ok {
return &net.UnixAddr{Name: s.Name, Net: "unixpacket"}
}
return nil
}
// from: go/src/pkg/net/ipsock.go
// IP6ZoneToString converts an IP6 Zone unix int to a net string
// returns "" if zone is 0
func IP6ZoneToString(zone int) string {
if zone == 0 {
return ""
}
if ifi, err := net.InterfaceByIndex(zone); err == nil {
return ifi.Name
}
return itod(uint(zone))
}
// IP6ZoneToInt converts an IP6 Zone net string to a unix int
// returns 0 if zone is ""
func IP6ZoneToInt(zone string) int {
if zone == "" {
return 0
}
if ifi, err := net.InterfaceByName(zone); err == nil {
return ifi.Index
}
n, _, _ := dtoi(zone, 0)
return n
}
// from: go/src/pkg/net/parse.go
// Convert i to decimal string.
func itod(i uint) string {
if i == 0 {
return "0"
}
// Assemble decimal in reverse order.
var b [32]byte
bp := len(b)
for ; i > 0; i /= 10 {
bp--
b[bp] = byte(i%10) + '0'
}
return string(b[bp:])
}
// Bigger than we need, not too big to worry about overflow
const big = 0xFFFFFF
// Decimal to integer starting at &s[i0].
// Returns number, new offset, success.
func dtoi(s string, i0 int) (n int, i int, ok bool) {
n = 0
for i = i0; i < len(s) && '0' <= s[i] && s[i] <= '9'; i++ {
n = n*10 + int(s[i]-'0')
if n >= big {
return 0, i, false
}
}
if i == i0 {
return 0, i, false
}
return n, i, true
}
// +build darwin dragonfly freebsd netbsd openbsd
package sockaddrnet
import (
"golang.org/x/sys/unix"
)
const (
AF_INET = unix.AF_INET
AF_INET6 = unix.AF_INET6
AF_UNIX = unix.AF_UNIX
AF_UNSPEC = unix.AF_UNSPEC
IPPROTO_IP = unix.IPPROTO_IP
IPPROTO_IPV4 = unix.IPPROTO_IPV4
IPPROTO_IPV6 = unix.IPPROTO_IPV6
IPPROTO_TCP = unix.IPPROTO_TCP
IPPROTO_UDP = unix.IPPROTO_UDP
SOCK_DGRAM = unix.SOCK_DGRAM
SOCK_STREAM = unix.SOCK_STREAM
SOCK_SEQPACKET = unix.SOCK_SEQPACKET
)
type Sockaddr = unix.Sockaddr
type SockaddrInet4 = unix.SockaddrInet4
type SockaddrInet6 = unix.SockaddrInet6
type SockaddrUnix = unix.SockaddrUnix
type RawSockaddrAny = unix.RawSockaddrAny
package sockaddrnet
import (
"golang.org/x/sys/unix"
)
const (
AF_INET = unix.AF_INET
AF_INET6 = unix.AF_INET6
AF_UNIX = unix.AF_UNIX
AF_UNSPEC = unix.AF_UNSPEC
IPPROTO_IP = unix.IPPROTO_IP
IPPROTO_IPV4 = unix.IPPROTO_IPIP
IPPROTO_IPV6 = unix.IPPROTO_IPV6
IPPROTO_TCP = unix.IPPROTO_TCP
IPPROTO_UDP = unix.IPPROTO_UDP
SOCK_DGRAM = unix.SOCK_DGRAM
SOCK_STREAM = unix.SOCK_STREAM
SOCK_SEQPACKET = unix.SOCK_SEQPACKET
)
type Sockaddr = unix.Sockaddr
type SockaddrInet4 = unix.SockaddrInet4
type SockaddrInet6 = unix.SockaddrInet6
type SockaddrUnix = unix.SockaddrUnix
type RawSockaddrAny = unix.RawSockaddrAny
package sockaddrnet
import (
"bytes"
"net"
"testing"
)
func assertIPEq(t *testing.T, ip net.IP, sa Sockaddr) {
switch s := sa.(type) {
case *SockaddrInet4:
if !bytes.Equal(s.Addr[:], ip.To4()) {
t.Error("IPs not equal")
}
case *SockaddrInet6:
if !bytes.Equal(s.Addr[:], ip.To16()) {
t.Error("IPs not equal")
}
default:
t.Error("not a known sockaddr")
}
}
func subtestIPSockaddr(t *testing.T, ip net.IP) {
assertIPEq(t, ip, IPAndZoneToSockaddr(ip, ""))
}
func TestIPAndZoneToSockaddr(t *testing.T) {
subtestIPSockaddr(t, net.ParseIP("127.0.0.1"))
subtestIPSockaddr(t, net.IPv4zero)
subtestIPSockaddr(t, net.IP(net.IPv4zero.To4()))
subtestIPSockaddr(t, net.IPv6unspecified)
assertIPEq(t, net.IPv4zero, IPAndZoneToSockaddr(nil, ""))
}
package sockaddrnet
import (
"golang.org/x/sys/windows"
)
const (
AF_INET = windows.AF_INET
AF_INET6 = windows.AF_INET6
AF_UNIX = windows.AF_UNIX
AF_UNSPEC = windows.AF_UNSPEC
IPPROTO_IP = windows.IPPROTO_IP
IPPROTO_IPV4 = 0x4 // windows.IPPROTO_IPV4 (missing)
IPPROTO_IPV6 = windows.IPPROTO_IPV6
IPPROTO_TCP = windows.IPPROTO_TCP
IPPROTO_UDP = windows.IPPROTO_UDP
SOCK_DGRAM = windows.SOCK_DGRAM
SOCK_STREAM = windows.SOCK_STREAM
SOCK_SEQPACKET = windows.SOCK_SEQPACKET
)
type Sockaddr = windows.Sockaddr
type SockaddrInet4 = windows.SockaddrInet4
type SockaddrInet6 = windows.SockaddrInet6
type SockaddrUnix = windows.SockaddrUnix
type RawSockaddrAny = windows.RawSockaddrAny
package sockaddr
import (
sockaddrnet "github.com/libp2p/go-sockaddr/net"
)
// Socklen is a type for the length of a sockaddr.
type Socklen uint
// SockaddrToAny converts a Sockaddr into a RawSockaddrAny
// The implementation is platform dependent.
func SockaddrToAny(sa sockaddrnet.Sockaddr) (*sockaddrnet.RawSockaddrAny, Socklen, error) {
return sockaddrToAny(sa)
}
// SockaddrToAny converts a RawSockaddrAny into a Sockaddr
// The implementation is platform dependent.
func AnyToSockaddr(rsa *sockaddrnet.RawSockaddrAny) (sockaddrnet.Sockaddr, error) {
return anyToSockaddr(rsa)
}
// +build darwin dragonfly freebsd netbsd openbsd
package sockaddr
import (
"syscall"
"unsafe"
"golang.org/x/sys/unix"
)
func sockaddrToAny(sa unix.Sockaddr) (*unix.RawSockaddrAny, Socklen, error) {
if sa == nil {
return nil, 0, syscall.EINVAL
}
switch sa := sa.(type) {
case *unix.SockaddrInet4:
if sa.Port < 0 || sa.Port > 0xFFFF {
return nil, 0, syscall.EINVAL
}
var raw unix.RawSockaddrInet4
raw.Len = unix.SizeofSockaddrInet4
raw.Family = unix.AF_INET
p := (*[2]byte)(unsafe.Pointer(&raw.Port))
p[0] = byte(sa.Port >> 8)
p[1] = byte(sa.Port)
for i := 0; i < len(sa.Addr); i++ {
raw.Addr[i] = sa.Addr[i]
}
return (*unix.RawSockaddrAny)(unsafe.Pointer(&raw)), Socklen(raw.Len), nil
case *unix.SockaddrInet6:
if sa.Port < 0 || sa.Port > 0xFFFF {
return nil, 0, syscall.EINVAL
}
var raw unix.RawSockaddrInet6
raw.Len = unix.SizeofSockaddrInet6
raw.Family = unix.AF_INET6
p := (*[2]byte)(unsafe.Pointer(&raw.Port))
p[0] = byte(sa.Port >> 8)
p[1] = byte(sa.Port)
raw.Scope_id = sa.ZoneId
for i := 0; i < len(sa.Addr); i++ {
raw.Addr[i] = sa.Addr[i]
}
return (*unix.RawSockaddrAny)(unsafe.Pointer(&raw)), Socklen(raw.Len), nil
case *unix.SockaddrUnix:
name := sa.Name
n := len(name)
var raw unix.RawSockaddrUnix
if n >= len(raw.Path) || n == 0 {
return nil, 0, syscall.EINVAL
}
raw.Len = byte(3 + n) // 2 for Family, Len; 1 for NUL
raw.Family = unix.AF_UNIX
for i := 0; i < n; i++ {
raw.Path[i] = int8(name[i])
}
return (*unix.RawSockaddrAny)(unsafe.Pointer(&raw)), Socklen(raw.Len), nil
case *unix.SockaddrDatalink:
if sa.Index == 0 {
return nil, 0, syscall.EINVAL
}
var raw unix.RawSockaddrDatalink
raw.Len = sa.Len
raw.Family = unix.AF_LINK
raw.Index = sa.Index
raw.Type = sa.Type
raw.Nlen = sa.Nlen
raw.Alen = sa.Alen
raw.Slen = sa.Slen
for i := 0; i < len(raw.Data); i++ {
raw.Data[i] = sa.Data[i]
}
return (*unix.RawSockaddrAny)(unsafe.Pointer(&raw)), unix.SizeofSockaddrDatalink, nil
}
return nil, 0, syscall.EAFNOSUPPORT
}
func anyToSockaddr(rsa *unix.RawSockaddrAny) (unix.Sockaddr, error) {
if rsa == nil {
return nil, syscall.EINVAL
}
switch rsa.Addr.Family {
case unix.AF_LINK:
pp := (*unix.RawSockaddrDatalink)(unsafe.Pointer(rsa))
sa := new(unix.SockaddrDatalink)
sa.Len = pp.Len
sa.Family = pp.Family
sa.Index = pp.Index
sa.Type = pp.Type
sa.Nlen = pp.Nlen
sa.Alen = pp.Alen
sa.Slen = pp.Slen
for i := 0; i < len(sa.Data); i++ {
sa.Data[i] = pp.Data[i]
}
return sa, nil
case unix.AF_UNIX:
pp := (*unix.RawSockaddrUnix)(unsafe.Pointer(rsa))
if pp.Len < 3 || pp.Len > unix.SizeofSockaddrUnix {
return nil, syscall.EINVAL
}
sa := new(unix.SockaddrUnix)
n := int(pp.Len) - 3 // subtract leading Family, Len, terminating NUL
for i := 0; i < n; i++ {
if pp.Path[i] == 0 {
// found early NUL; assume Len is overestimating
n = i
break
}
}
bytes := (*[10000]byte)(unsafe.Pointer(&pp.Path[0]))[0:n]
sa.Name = string(bytes)
return sa, nil
case unix.AF_INET:
pp := (*unix.RawSockaddrInet4)(unsafe.Pointer(rsa))
sa := new(unix.SockaddrInet4)
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
sa.Port = int(p[0])<<8 + int(p[1])
for i := 0; i < len(sa.Addr); i++ {
sa.Addr[i] = pp.Addr[i]
}
return sa, nil
case unix.AF_INET6:
pp := (*unix.RawSockaddrInet6)(unsafe.Pointer(rsa))
sa := new(unix.SockaddrInet6)
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
sa.Port = int(p[0])<<8 + int(p[1])
sa.ZoneId = pp.Scope_id
for i := 0; i < len(sa.Addr); i++ {
sa.Addr[i] = pp.Addr[i]
}
return sa, nil
}
return nil, syscall.EAFNOSUPPORT
}
package sockaddr
import (
"syscall"
"unsafe"
"golang.org/x/sys/unix"
)
func sockaddrToAny(sa unix.Sockaddr) (*unix.RawSockaddrAny, Socklen, error) {
if sa == nil {
return nil, 0, syscall.EINVAL
}
switch sa := sa.(type) {
case *unix.SockaddrInet4:
if sa.Port < 0 || sa.Port > 0xFFFF {
return nil, 0, syscall.EINVAL
}
var raw unix.RawSockaddrInet4
raw.Family = unix.AF_INET
p := (*[2]byte)(unsafe.Pointer(&raw.Port))
p[0] = byte(sa.Port >> 8)
p[1] = byte(sa.Port)
for i := 0; i < len(sa.Addr); i++ {
raw.Addr[i] = sa.Addr[i]
}
return (*unix.RawSockaddrAny)(unsafe.Pointer(&raw)), unix.SizeofSockaddrInet4, nil
case *unix.SockaddrInet6:
if sa.Port < 0 || sa.Port > 0xFFFF {
return nil, 0, syscall.EINVAL
}
var raw unix.RawSockaddrInet6
raw.Family = unix.AF_INET6
p := (*[2]byte)(unsafe.Pointer(&raw.Port))
p[0] = byte(sa.Port >> 8)
p[1] = byte(sa.Port)
raw.Scope_id = sa.ZoneId
for i := 0; i < len(sa.Addr); i++ {
raw.Addr[i] = sa.Addr[i]
}
return (*unix.RawSockaddrAny)(unsafe.Pointer(&raw)), unix.SizeofSockaddrInet6, nil
case *unix.SockaddrUnix:
name := sa.Name
n := len(name)
var raw unix.RawSockaddrUnix
if n >= len(raw.Path) {
return nil, 0, syscall.EINVAL
}
raw.Family = unix.AF_UNIX
for i := 0; i < n; i++ {
raw.Path[i] = int8(name[i])
}
// length is family (uint16), name, NUL.
sl := Socklen(2)
if n > 0 {
sl += Socklen(n) + 1
}
if raw.Path[0] == '@' {
raw.Path[0] = 0
// Don't count trailing NUL for abstract address.
sl--
}
return (*unix.RawSockaddrAny)(unsafe.Pointer(&raw)), sl, nil
case *unix.SockaddrLinklayer:
if sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff {
return nil, 0, syscall.EINVAL
}
var raw unix.RawSockaddrLinklayer
raw.Family = unix.AF_PACKET
raw.Protocol = sa.Protocol
raw.Ifindex = int32(sa.Ifindex)
raw.Hatype = sa.Hatype
raw.Pkttype = sa.Pkttype
raw.Halen = sa.Halen
for i := 0; i < len(sa.Addr); i++ {
raw.Addr[i] = sa.Addr[i]
}
return (*unix.RawSockaddrAny)(unsafe.Pointer(&raw)), unix.SizeofSockaddrLinklayer, nil
}
return nil, 0, syscall.EAFNOSUPPORT
}
func anyToSockaddr(rsa *unix.RawSockaddrAny) (unix.Sockaddr, error) {
if rsa == nil {
return nil, syscall.EINVAL
}
switch rsa.Addr.Family {
case unix.AF_NETLINK:
pp := (*unix.RawSockaddrNetlink)(unsafe.Pointer(rsa))
sa := new(unix.SockaddrNetlink)
sa.Family = pp.Family
sa.Pad = pp.Pad
sa.Pid = pp.Pid
sa.Groups = pp.Groups
return sa, nil
case unix.AF_PACKET:
pp := (*unix.RawSockaddrLinklayer)(unsafe.Pointer(rsa))
sa := new(unix.SockaddrLinklayer)
sa.Protocol = pp.Protocol
sa.Ifindex = int(pp.Ifindex)
sa.Hatype = pp.Hatype
sa.Pkttype = pp.Pkttype
sa.Halen = pp.Halen
for i := 0; i < len(sa.Addr); i++ {
sa.Addr[i] = pp.Addr[i]
}
return sa, nil
case unix.AF_UNIX:
pp := (*unix.RawSockaddrUnix)(unsafe.Pointer(rsa))
sa := new(unix.SockaddrUnix)
if pp.Path[0] == 0 {
// "Abstract" Unix domain socket.
// Rewrite leading NUL as @ for textual display.
// (This is the standard convention.)
// Not friendly to overwrite in place,
// but the callers below don't care.
pp.Path[0] = '@'
}
// Assume path ends at NUL.
// This is not technically the Linux semantics for
// abstract Unix domain sockets--they are supposed
// to be uninterpreted fixed-size binary blobs--but
// everyone uses this convention.
n := 0
for n < len(pp.Path) && pp.Path[n] != 0 {
n++
}
bytes := (*[10000]byte)(unsafe.Pointer(&pp.Path[0]))[0:n]
sa.Name = string(bytes)
return sa, nil
case unix.AF_INET:
pp := (*unix.RawSockaddrInet4)(unsafe.Pointer(rsa))
sa := new(unix.SockaddrInet4)
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
sa.Port = int(p[0])<<8 + int(p[1])
for i := 0; i < len(sa.Addr); i++ {
sa.Addr[i] = pp.Addr[i]
}
return sa, nil
case unix.AF_INET6:
pp := (*unix.RawSockaddrInet6)(unsafe.Pointer(rsa))
sa := new(unix.SockaddrInet6)
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
sa.Port = int(p[0])<<8 + int(p[1])
sa.ZoneId = pp.Scope_id
for i := 0; i < len(sa.Addr); i++ {
sa.Addr[i] = pp.Addr[i]
}
return sa, nil
}
return nil, syscall.EAFNOSUPPORT
}
package sockaddr
// import (
// "unix"
// "unsafe"
// )
// func sockaddrToAny(sa unix.Sockaddr) (*unix.RawSockaddrAny, Socklen, error) {
// if sa == nil {
// return nil, 0, unix.EINVAL
// }
// switch sa.(type) {
// case *unix.SockaddrInet4:
// case *unix.SockaddrInet6:
// case *unix.SockaddrUnix:
// case *unix.SockaddrDatalink:
// }
// return nil, 0, unix.EAFNOSUPPORT
// }
// func anyToSockaddr(rsa *unix.RawSockaddrAny) (unix.Sockaddr, error) {
// if rsa == nil {
// return nil, 0, unix.EINVAL
// }
// switch rsa.Addr.Family {
// case unix.AF_NETLINK:
// case unix.AF_PACKET:
// case unix.AF_UNIX:
// case unix.AF_INET:
// case unix.AF_INET6:
// }
// return nil, unix.EAFNOSUPPORT
// }
package sockaddr
import (
"syscall"
"unsafe"
"golang.org/x/sys/windows"
)
func sockaddrToAny(sa windows.Sockaddr) (*windows.RawSockaddrAny, Socklen, error) {
if sa == nil {
return nil, 0, syscall.EINVAL
}
switch sa := sa.(type) {
case *windows.SockaddrInet4:
if sa.Port < 0 || sa.Port > 0xFFFF {
return nil, 0, syscall.EINVAL
}
raw := new(windows.RawSockaddrAny)
raw.Addr.Family = windows.AF_INET
raw4 := (*windows.RawSockaddrInet4)(unsafe.Pointer(raw))
p := (*[2]byte)(unsafe.Pointer(&raw4.Port))
p[0] = byte(sa.Port >> 8)
p[1] = byte(sa.Port)
for i := 0; i < len(sa.Addr); i++ {
raw4.Addr[i] = sa.Addr[i]
}
return raw, Socklen(unsafe.Sizeof(*raw4)), nil
case *windows.SockaddrInet6:
if sa.Port < 0 || sa.Port > 0xFFFF {
return nil, 0, syscall.EINVAL
}
raw := new(windows.RawSockaddrAny)
raw.Addr.Family = windows.AF_INET6
raw6 := (*windows.RawSockaddrInet6)(unsafe.Pointer(raw))
p := (*[2]byte)(unsafe.Pointer(&raw6.Port))
p[0] = byte(sa.Port >> 8)
p[1] = byte(sa.Port)
raw6.Scope_id = sa.ZoneId
for i := 0; i < len(sa.Addr); i++ {
raw6.Addr[i] = sa.Addr[i]
}
return raw, Socklen(unsafe.Sizeof(*raw6)), nil
case *windows.SockaddrUnix:
return nil, 0, syscall.EWINDOWS
}
return nil, 0, syscall.EAFNOSUPPORT
}
func anyToSockaddr(rsa *windows.RawSockaddrAny) (windows.Sockaddr, error) {
if rsa == nil {
return nil, syscall.EINVAL
}
switch rsa.Addr.Family {
case windows.AF_UNIX:
return nil, syscall.EWINDOWS
case windows.AF_INET:
pp := (*windows.RawSockaddrInet4)(unsafe.Pointer(rsa))
sa := new(windows.SockaddrInet4)
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
sa.Port = int(p[0])<<8 + int(p[1])
for i := 0; i < len(sa.Addr); i++ {
sa.Addr[i] = pp.Addr[i]
}
return sa, nil
case windows.AF_INET6:
pp := (*windows.RawSockaddrInet6)(unsafe.Pointer(rsa))
sa := new(windows.SockaddrInet6)
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
sa.Port = int(p[0])<<8 + int(p[1])
sa.ZoneId = pp.Scope_id
for i := 0; i < len(sa.Addr); i++ {
sa.Addr[i] = pp.Addr[i]
}
return sa, nil
}
return nil, syscall.EAFNOSUPPORT
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment