aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/ishidawataru/sctp/sctp.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/ishidawataru/sctp/sctp.go')
-rw-r--r--vendor/github.com/ishidawataru/sctp/sctp.go88
1 files changed, 56 insertions, 32 deletions
diff --git a/vendor/github.com/ishidawataru/sctp/sctp.go b/vendor/github.com/ishidawataru/sctp/sctp.go
index cac1a889c..30d619640 100644
--- a/vendor/github.com/ishidawataru/sctp/sctp.go
+++ b/vendor/github.com/ishidawataru/sctp/sctp.go
@@ -197,37 +197,58 @@ func htons(h uint16) uint16 {
var ntohs = htons
-func setNumOstreams(fd, num int) error {
- param := InitMsg{
- NumOstreams: uint16(num),
- }
- optlen := unsafe.Sizeof(param)
- _, _, err := setsockopt(fd, SCTP_INITMSG, uintptr(unsafe.Pointer(&param)), uintptr(optlen))
+// setInitOpts sets options for an SCTP association initialization
+// see https://tools.ietf.org/html/rfc4960#page-25
+func setInitOpts(fd int, options InitMsg) error {
+ optlen := unsafe.Sizeof(options)
+ _, _, err := setsockopt(fd, SCTP_INITMSG, uintptr(unsafe.Pointer(&options)), uintptr(optlen))
return err
}
+func setNumOstreams(fd, num int) error {
+ return setInitOpts(fd, InitMsg{NumOstreams: uint16(num)})
+}
+
type SCTPAddr struct {
- IP []net.IP
- Port int
+ IPAddrs []net.IPAddr
+ Port int
}
func (a *SCTPAddr) ToRawSockAddrBuf() []byte {
- buf := []byte{}
p := htons(uint16(a.Port))
- for _, ip := range a.IP {
- if ip.To4() != nil {
+ if len(a.IPAddrs) == 0 { // if a.IPAddrs list is empty - fall back to IPv4 zero addr
+ s := syscall.RawSockaddrInet4{
+ Family: syscall.AF_INET,
+ Port: p,
+ }
+ copy(s.Addr[:], net.IPv4zero)
+ return toBuf(s)
+ }
+ buf := []byte{}
+ for _, ip := range a.IPAddrs {
+ ipBytes := ip.IP
+ if len(ipBytes) == 0 {
+ ipBytes = net.IPv4zero
+ }
+ if ip4 := ipBytes.To4(); ip4 != nil {
s := syscall.RawSockaddrInet4{
Family: syscall.AF_INET,
Port: p,
}
- copy(s.Addr[:], ip.To4())
+ copy(s.Addr[:], ip4)
buf = append(buf, toBuf(s)...)
} else {
+ var scopeid uint32
+ ifi, err := net.InterfaceByName(ip.Zone)
+ if err == nil {
+ scopeid = uint32(ifi.Index)
+ }
s := syscall.RawSockaddrInet6{
- Family: syscall.AF_INET6,
- Port: p,
+ Family: syscall.AF_INET6,
+ Port: p,
+ Scope_id: scopeid,
}
- copy(s.Addr[:], ip)
+ copy(s.Addr[:], ipBytes)
buf = append(buf, toBuf(s)...)
}
}
@@ -237,15 +258,15 @@ func (a *SCTPAddr) ToRawSockAddrBuf() []byte {
func (a *SCTPAddr) String() string {
var b bytes.Buffer
- for n, i := range a.IP {
- if a.IP[n].To4() != nil {
+ for n, i := range a.IPAddrs {
+ if i.IP.To4() != nil {
b.WriteString(i.String())
- } else if a.IP[n].To16() != nil {
+ } else if i.IP.To16() != nil {
b.WriteRune('[')
b.WriteString(i.String())
b.WriteRune(']')
}
- if n < len(a.IP)-1 {
+ if n < len(a.IPAddrs)-1 {
b.WriteRune('/')
}
}
@@ -260,6 +281,7 @@ func ResolveSCTPAddr(network, addrs string) (*SCTPAddr, error) {
tcpnet := ""
switch network {
case "", "sctp":
+ tcpnet = "tcp"
case "sctp4":
tcpnet = "tcp4"
case "sctp6":
@@ -271,26 +293,26 @@ func ResolveSCTPAddr(network, addrs string) (*SCTPAddr, error) {
if len(elems) == 0 {
return nil, fmt.Errorf("invalid input: %s", addrs)
}
- ipaddrs := make([]net.IP, 0, len(elems))
+ ipaddrs := make([]net.IPAddr, 0, len(elems))
for _, e := range elems[:len(elems)-1] {
tcpa, err := net.ResolveTCPAddr(tcpnet, e+":")
if err != nil {
return nil, err
}
- ipaddrs = append(ipaddrs, tcpa.IP)
+ ipaddrs = append(ipaddrs, net.IPAddr{IP: tcpa.IP, Zone: tcpa.Zone})
}
tcpa, err := net.ResolveTCPAddr(tcpnet, elems[len(elems)-1])
if err != nil {
return nil, err
}
if tcpa.IP != nil {
- ipaddrs = append(ipaddrs, tcpa.IP)
+ ipaddrs = append(ipaddrs, net.IPAddr{IP: tcpa.IP, Zone: tcpa.Zone})
} else {
ipaddrs = nil
}
return &SCTPAddr{
- IP: ipaddrs,
- Port: tcpa.Port,
+ IPAddrs: ipaddrs,
+ Port: tcpa.Port,
}, nil
}
@@ -357,15 +379,12 @@ func (c *SCTPConn) Read(b []byte) (int, error) {
}
func (c *SCTPConn) SetInitMsg(numOstreams, maxInstreams, maxAttempts, maxInitTimeout int) error {
- param := InitMsg{
+ return setInitOpts(c.fd(), InitMsg{
NumOstreams: uint16(numOstreams),
MaxInstreams: uint16(maxInstreams),
MaxAttempts: uint16(maxAttempts),
MaxInitTimeout: uint16(maxInitTimeout),
- }
- optlen := unsafe.Sizeof(param)
- _, _, err := setsockopt(c.fd(), SCTP_INITMSG, uintptr(unsafe.Pointer(&param)), uintptr(optlen))
- return err
+ })
}
func (c *SCTPConn) SubscribeEvents(flags int) error {
@@ -473,7 +492,7 @@ func (c *SCTPConn) GetDefaultSentParam() (*SndRcvInfo, error) {
func resolveFromRawAddr(ptr unsafe.Pointer, n int) (*SCTPAddr, error) {
addr := &SCTPAddr{
- IP: make([]net.IP, n),
+ IPAddrs: make([]net.IPAddr, n),
}
switch family := (*(*syscall.RawSockaddrAny)(ptr)).Addr.Family; family {
@@ -484,7 +503,7 @@ func resolveFromRawAddr(ptr unsafe.Pointer, n int) (*SCTPAddr, error) {
for i := 0; i < n; i++ {
a := *(*syscall.RawSockaddrInet4)(unsafe.Pointer(
uintptr(ptr) + size*uintptr(i)))
- addr.IP[i] = a.Addr[:]
+ addr.IPAddrs[i] = net.IPAddr{IP: a.Addr[:]}
}
case syscall.AF_INET6:
addr.Port = int(ntohs(uint16((*(*syscall.RawSockaddrInet4)(ptr)).Port)))
@@ -493,7 +512,12 @@ func resolveFromRawAddr(ptr unsafe.Pointer, n int) (*SCTPAddr, error) {
for i := 0; i < n; i++ {
a := *(*syscall.RawSockaddrInet6)(unsafe.Pointer(
uintptr(ptr) + size*uintptr(i)))
- addr.IP[i] = a.Addr[:]
+ var zone string
+ ifi, err := net.InterfaceByIndex(int(a.Scope_id))
+ if err == nil {
+ zone = ifi.Name
+ }
+ addr.IPAddrs[i] = net.IPAddr{IP: a.Addr[:], Zone: zone}
}
default:
return nil, fmt.Errorf("unknown address family: %d", family)