diff options
Diffstat (limited to 'vendor/github.com/ishidawataru/sctp')
-rw-r--r-- | vendor/github.com/ishidawataru/sctp/.gitignore | 2 | ||||
-rw-r--r-- | vendor/github.com/ishidawataru/sctp/.travis.yml | 1 | ||||
-rw-r--r-- | vendor/github.com/ishidawataru/sctp/GO_LICENSE | 27 | ||||
-rw-r--r-- | vendor/github.com/ishidawataru/sctp/ipsock_linux.go | 218 | ||||
-rw-r--r-- | vendor/github.com/ishidawataru/sctp/sctp.go | 88 | ||||
-rw-r--r-- | vendor/github.com/ishidawataru/sctp/sctp_linux.go | 111 | ||||
-rw-r--r-- | vendor/github.com/ishidawataru/sctp/sctp_unsupported.go | 12 |
7 files changed, 376 insertions, 83 deletions
diff --git a/vendor/github.com/ishidawataru/sctp/.gitignore b/vendor/github.com/ishidawataru/sctp/.gitignore index a1338d685..cf2d826c1 100644 --- a/vendor/github.com/ishidawataru/sctp/.gitignore +++ b/vendor/github.com/ishidawataru/sctp/.gitignore @@ -12,3 +12,5 @@ # Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 .glide/ + +example/example diff --git a/vendor/github.com/ishidawataru/sctp/.travis.yml b/vendor/github.com/ishidawataru/sctp/.travis.yml index 64f85ef28..e72c57864 100644 --- a/vendor/github.com/ishidawataru/sctp/.travis.yml +++ b/vendor/github.com/ishidawataru/sctp/.travis.yml @@ -4,6 +4,7 @@ go: - 1.7 - 1.8 - 1.9 + - "1.10" script: - go test -v -race ./... diff --git a/vendor/github.com/ishidawataru/sctp/GO_LICENSE b/vendor/github.com/ishidawataru/sctp/GO_LICENSE new file mode 100644 index 000000000..6a66aea5e --- /dev/null +++ b/vendor/github.com/ishidawataru/sctp/GO_LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009 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. diff --git a/vendor/github.com/ishidawataru/sctp/ipsock_linux.go b/vendor/github.com/ishidawataru/sctp/ipsock_linux.go new file mode 100644 index 000000000..f5632b72d --- /dev/null +++ b/vendor/github.com/ishidawataru/sctp/ipsock_linux.go @@ -0,0 +1,218 @@ +package sctp + +import ( + "net" + "os" + "sync" + "syscall" +) + +//from https://github.com/golang/go +// Boolean to int. +func boolint(b bool) int { + if b { + return 1 + } + return 0 +} + +//from https://github.com/golang/go +func ipToSockaddr(family int, ip net.IP, port int, zone string) (syscall.Sockaddr, error) { + switch family { + case syscall.AF_INET: + if len(ip) == 0 { + ip = net.IPv4zero + } + ip4 := ip.To4() + if ip4 == nil { + return nil, &net.AddrError{Err: "non-IPv4 address", Addr: ip.String()} + } + sa := &syscall.SockaddrInet4{Port: port} + copy(sa.Addr[:], ip4) + return sa, nil + case syscall.AF_INET6: + // In general, an IP wildcard address, which is either + // "0.0.0.0" or "::", means the entire IP addressing + // space. For some historical reason, it is used to + // specify "any available address" on some operations + // of IP node. + // + // When the IP node supports IPv4-mapped IPv6 address, + // we allow an listener to listen to the wildcard + // address of both IP addressing spaces by specifying + // IPv6 wildcard address. + if len(ip) == 0 || ip.Equal(net.IPv4zero) { + ip = net.IPv6zero + } + // We accept any IPv6 address including IPv4-mapped + // IPv6 address. + ip6 := ip.To16() + if ip6 == nil { + return nil, &net.AddrError{Err: "non-IPv6 address", Addr: ip.String()} + } + //we set ZoneId to 0, as currently we use this functon only to probe the IP capabilities of the host + //if real Zone handling is required, the zone cache implementation in golang/net should be pulled here + sa := &syscall.SockaddrInet6{Port: port, ZoneId: 0} + copy(sa.Addr[:], ip6) + return sa, nil + } + return nil, &net.AddrError{Err: "invalid address family", Addr: ip.String()} +} + +//from https://github.com/golang/go +func sockaddr(a *net.TCPAddr, family int) (syscall.Sockaddr, error) { + if a == nil { + return nil, nil + } + return ipToSockaddr(family, a.IP, a.Port, a.Zone) +} + +//from https://github.com/golang/go +type ipStackCapabilities struct { + sync.Once // guards following + ipv4Enabled bool + ipv6Enabled bool + ipv4MappedIPv6Enabled bool +} + +//from https://github.com/golang/go +var ipStackCaps ipStackCapabilities + +//from https://github.com/golang/go +// supportsIPv4 reports whether the platform supports IPv4 networking +// functionality. +func supportsIPv4() bool { + ipStackCaps.Once.Do(ipStackCaps.probe) + return ipStackCaps.ipv4Enabled +} + +//from https://github.com/golang/go +// supportsIPv6 reports whether the platform supports IPv6 networking +// functionality. +func supportsIPv6() bool { + ipStackCaps.Once.Do(ipStackCaps.probe) + return ipStackCaps.ipv6Enabled +} + +//from https://github.com/golang/go +// supportsIPv4map reports whether the platform supports mapping an +// IPv4 address inside an IPv6 address at transport layer +// protocols. See RFC 4291, RFC 4038 and RFC 3493. +func supportsIPv4map() bool { + ipStackCaps.Once.Do(ipStackCaps.probe) + return ipStackCaps.ipv4MappedIPv6Enabled +} + +//from https://github.com/golang/go +// Probe probes IPv4, IPv6 and IPv4-mapped IPv6 communication +// capabilities which are controlled by the IPV6_V6ONLY socket option +// and kernel configuration. +// +// Should we try to use the IPv4 socket interface if we're only +// dealing with IPv4 sockets? As long as the host system understands +// IPv4-mapped IPv6, it's okay to pass IPv4-mapeed IPv6 addresses to +// the IPv6 interface. That simplifies our code and is most +// general. Unfortunately, we need to run on kernels built without +// IPv6 support too. So probe the kernel to figure it out. +func (p *ipStackCapabilities) probe() { + s, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_STREAM, syscall.IPPROTO_TCP) + switch err { + case syscall.EAFNOSUPPORT, syscall.EPROTONOSUPPORT: + case nil: + syscall.Close(s) + p.ipv4Enabled = true + } + var probes = []struct { + laddr net.TCPAddr + value int + }{ + // IPv6 communication capability + {laddr: net.TCPAddr{IP: net.IPv6loopback}, value: 1}, + // IPv4-mapped IPv6 address communication capability + {laddr: net.TCPAddr{IP: net.IPv4(127, 0, 0, 1)}, value: 0}, + } + + for i := range probes { + s, err := syscall.Socket(syscall.AF_INET6, syscall.SOCK_STREAM, syscall.IPPROTO_TCP) + if err != nil { + continue + } + defer syscall.Close(s) + syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, probes[i].value) + sa, err := sockaddr(&(probes[i].laddr), syscall.AF_INET6) + if err != nil { + continue + } + if err := syscall.Bind(s, sa); err != nil { + continue + } + if i == 0 { + p.ipv6Enabled = true + } else { + p.ipv4MappedIPv6Enabled = true + } + } +} + +//from https://github.com/golang/go +//Change: we check the first IP address in the list of candidate SCTP IP addresses +func (a *SCTPAddr) isWildcard() bool { + if a == nil { + return true + } + if 0 == len(a.IPAddrs) { + return true + } + + return a.IPAddrs[0].IP.IsUnspecified() +} + +func (a *SCTPAddr) family() int { + if a != nil { + for _, ip := range a.IPAddrs { + if ip.IP.To4() == nil { + return syscall.AF_INET6 + } + } + } + return syscall.AF_INET +} + +//from https://github.com/golang/go +func favoriteAddrFamily(network string, laddr *SCTPAddr, raddr *SCTPAddr, mode string) (family int, ipv6only bool) { + switch network[len(network)-1] { + case '4': + return syscall.AF_INET, false + case '6': + return syscall.AF_INET6, true + } + + if mode == "listen" && (laddr == nil || laddr.isWildcard()) { + if supportsIPv4map() || !supportsIPv4() { + return syscall.AF_INET6, false + } + if laddr == nil { + return syscall.AF_INET, false + } + return laddr.family(), false + } + + if (laddr == nil || laddr.family() == syscall.AF_INET) && + (raddr == nil || raddr.family() == syscall.AF_INET) { + return syscall.AF_INET, false + } + return syscall.AF_INET6, false +} + +//from https://github.com/golang/go +//Changes: it is for SCTP only +func setDefaultSockopts(s int, family int, ipv6only bool) error { + if family == syscall.AF_INET6 { + // Allow both IP versions even if the OS default + // is otherwise. Note that some operating systems + // never admit this option. + syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, boolint(ipv6only)) + } + // Allow broadcast. + return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1)) +} 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(¶m)), 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(¶m)), 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) diff --git a/vendor/github.com/ishidawataru/sctp/sctp_linux.go b/vendor/github.com/ishidawataru/sctp/sctp_linux.go index f93ab8622..5a6ad9378 100644 --- a/vendor/github.com/ishidawataru/sctp/sctp_linux.go +++ b/vendor/github.com/ishidawataru/sctp/sctp_linux.go @@ -3,7 +3,6 @@ package sctp import ( - "fmt" "io" "net" "sync/atomic" @@ -115,31 +114,14 @@ func (c *SCTPConn) Close() error { return syscall.EBADF } +// ListenSCTP - start listener on specified address/port func ListenSCTP(net string, laddr *SCTPAddr) (*SCTPListener, error) { - af := syscall.AF_INET - switch net { - case "sctp": - hasv6 := func(addr *SCTPAddr) bool { - if addr == nil { - return false - } - for _, ip := range addr.IP { - if ip.To4() == nil { - return true - } - } - return false - } - if hasv6(laddr) { - af = syscall.AF_INET6 - } - case "sctp4": - case "sctp6": - af = syscall.AF_INET6 - default: - return nil, fmt.Errorf("invalid net: %s", net) - } + return ListenSCTPExt(net, laddr, InitMsg{NumOstreams: SCTP_MAX_STREAM}) +} +// ListenSCTPExt - start listener on specified address/port with given SCTP options +func ListenSCTPExt(network string, laddr *SCTPAddr, options InitMsg) (*SCTPListener, error) { + af, ipv6only := favoriteAddrFamily(network, laddr, nil, "listen") sock, err := syscall.Socket( af, syscall.SOCK_STREAM, @@ -148,11 +130,30 @@ func ListenSCTP(net string, laddr *SCTPAddr) (*SCTPListener, error) { if err != nil { return nil, err } - err = setNumOstreams(sock, SCTP_MAX_STREAM) + + // close socket on error + defer func() { + if err != nil { + syscall.Close(sock) + } + }() + if err = setDefaultSockopts(sock, af, ipv6only); err != nil { + return nil, err + } + err = setInitOpts(sock, options) if err != nil { return nil, err } - if laddr != nil && len(laddr.IP) != 0 { + + if laddr != nil { + // If IP address and/or port was not provided so far, let's use the unspecified IPv4 or IPv6 address + if len(laddr.IPAddrs) == 0 { + if af == syscall.AF_INET { + laddr.IPAddrs = append(laddr.IPAddrs, net.IPAddr{IP: net.IPv4zero}) + } else if af == syscall.AF_INET6 { + laddr.IPAddrs = append(laddr.IPAddrs, net.IPAddr{IP: net.IPv6zero}) + } + } err := SCTPBind(sock, laddr, SCTP_BINDX_ADD_ADDR) if err != nil { return nil, err @@ -167,40 +168,30 @@ func ListenSCTP(net string, laddr *SCTPAddr) (*SCTPListener, error) { }, nil } -func (ln *SCTPListener) Accept() (net.Conn, error) { +// AcceptSCTP waits for and returns the next SCTP connection to the listener. +func (ln *SCTPListener) AcceptSCTP() (*SCTPConn, error) { fd, _, err := syscall.Accept4(ln.fd, 0) return NewSCTPConn(fd, nil), err } +// Accept waits for and returns the next connection connection to the listener. +func (ln *SCTPListener) Accept() (net.Conn, error) { + return ln.AcceptSCTP() +} + func (ln *SCTPListener) Close() error { syscall.Shutdown(ln.fd, syscall.SHUT_RDWR) return syscall.Close(ln.fd) } +// DialSCTP - bind socket to laddr (if given) and connect to raddr func DialSCTP(net string, laddr, raddr *SCTPAddr) (*SCTPConn, error) { - af := syscall.AF_INET - switch net { - case "sctp": - hasv6 := func(addr *SCTPAddr) bool { - if addr == nil { - return false - } - for _, ip := range addr.IP { - if ip.To4() == nil { - return true - } - } - return false - } - if hasv6(laddr) || hasv6(raddr) { - af = syscall.AF_INET6 - } - case "sctp4": - case "sctp6": - af = syscall.AF_INET6 - default: - return nil, fmt.Errorf("invalid net: %s", net) - } + return DialSCTPExt(net, laddr, raddr, InitMsg{NumOstreams: SCTP_MAX_STREAM}) +} + +// DialSCTPExt - same as DialSCTP but with given SCTP options +func DialSCTPExt(network string, laddr, raddr *SCTPAddr, options InitMsg) (*SCTPConn, error) { + af, ipv6only := favoriteAddrFamily(network, laddr, raddr, "dial") sock, err := syscall.Socket( af, syscall.SOCK_STREAM, @@ -209,11 +200,29 @@ func DialSCTP(net string, laddr, raddr *SCTPAddr) (*SCTPConn, error) { if err != nil { return nil, err } - err = setNumOstreams(sock, SCTP_MAX_STREAM) + + // close socket on error + defer func() { + if err != nil { + syscall.Close(sock) + } + }() + if err = setDefaultSockopts(sock, af, ipv6only); err != nil { + return nil, err + } + err = setInitOpts(sock, options) if err != nil { return nil, err } if laddr != nil { + // If IP address and/or port was not provided so far, let's use the unspecified IPv4 or IPv6 address + if len(laddr.IPAddrs) == 0 { + if af == syscall.AF_INET { + laddr.IPAddrs = append(laddr.IPAddrs, net.IPAddr{IP: net.IPv4zero}) + } else if af == syscall.AF_INET6 { + laddr.IPAddrs = append(laddr.IPAddrs, net.IPAddr{IP: net.IPv6zero}) + } + } err := SCTPBind(sock, laddr, SCTP_BINDX_ADD_ADDR) if err != nil { return nil, err diff --git a/vendor/github.com/ishidawataru/sctp/sctp_unsupported.go b/vendor/github.com/ishidawataru/sctp/sctp_unsupported.go index adcbf78b4..e5415843d 100644 --- a/vendor/github.com/ishidawataru/sctp/sctp_unsupported.go +++ b/vendor/github.com/ishidawataru/sctp/sctp_unsupported.go @@ -34,10 +34,18 @@ func ListenSCTP(net string, laddr *SCTPAddr) (*SCTPListener, error) { return nil, ErrUnsupported } +func ListenSCTPExt(net string, laddr *SCTPAddr, options InitMsg) (*SCTPListener, error) { + return nil, ErrUnsupported +} + func (ln *SCTPListener) Accept() (net.Conn, error) { return nil, ErrUnsupported } +func (ln *SCTPListener) AcceptSCTP() (*SCTPConn, error) { + return nil, ErrUnsupported +} + func (ln *SCTPListener) Close() error { return ErrUnsupported } @@ -45,3 +53,7 @@ func (ln *SCTPListener) Close() error { func DialSCTP(net string, laddr, raddr *SCTPAddr) (*SCTPConn, error) { return nil, ErrUnsupported } + +func DialSCTPExt(network string, laddr, raddr *SCTPAddr, options InitMsg) (*SCTPConn, error) { + return nil, ErrUnsupported +} |