diff options
Diffstat (limited to 'vendor/github.com/ishidawataru/sctp/sctp_linux.go')
-rw-r--r-- | vendor/github.com/ishidawataru/sctp/sctp_linux.go | 305 |
1 files changed, 0 insertions, 305 deletions
diff --git a/vendor/github.com/ishidawataru/sctp/sctp_linux.go b/vendor/github.com/ishidawataru/sctp/sctp_linux.go deleted file mode 100644 index d96d09e5c..000000000 --- a/vendor/github.com/ishidawataru/sctp/sctp_linux.go +++ /dev/null @@ -1,305 +0,0 @@ -// +build linux,!386 -// Copyright 2019 Wataru Ishida. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -// implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package sctp - -import ( - "io" - "net" - "sync/atomic" - "syscall" - "unsafe" -) - -func setsockopt(fd int, optname, optval, optlen uintptr) (uintptr, uintptr, error) { - // FIXME: syscall.SYS_SETSOCKOPT is undefined on 386 - r0, r1, errno := syscall.Syscall6(syscall.SYS_SETSOCKOPT, - uintptr(fd), - SOL_SCTP, - optname, - optval, - optlen, - 0) - if errno != 0 { - return r0, r1, errno - } - return r0, r1, nil -} - -func getsockopt(fd int, optname, optval, optlen uintptr) (uintptr, uintptr, error) { - // FIXME: syscall.SYS_GETSOCKOPT is undefined on 386 - r0, r1, errno := syscall.Syscall6(syscall.SYS_GETSOCKOPT, - uintptr(fd), - SOL_SCTP, - optname, - optval, - optlen, - 0) - if errno != 0 { - return r0, r1, errno - } - return r0, r1, nil -} - -type rawConn struct { - sockfd int -} - -func (r rawConn) Control(f func(fd uintptr)) error { - f(uintptr(r.sockfd)) - return nil -} - -func (r rawConn) Read(f func(fd uintptr) (done bool)) error { - panic("not implemented") -} - -func (r rawConn) Write(f func(fd uintptr) (done bool)) error { - panic("not implemented") -} - -func (c *SCTPConn) SCTPWrite(b []byte, info *SndRcvInfo) (int, error) { - var cbuf []byte - if info != nil { - cmsgBuf := toBuf(info) - hdr := &syscall.Cmsghdr{ - Level: syscall.IPPROTO_SCTP, - Type: SCTP_CMSG_SNDRCV, - } - - // bitwidth of hdr.Len is platform-specific, - // so we use hdr.SetLen() rather than directly setting hdr.Len - hdr.SetLen(syscall.CmsgSpace(len(cmsgBuf))) - cbuf = append(toBuf(hdr), cmsgBuf...) - } - return syscall.SendmsgN(c.fd(), b, cbuf, nil, 0) -} - -func parseSndRcvInfo(b []byte) (*SndRcvInfo, error) { - msgs, err := syscall.ParseSocketControlMessage(b) - if err != nil { - return nil, err - } - for _, m := range msgs { - if m.Header.Level == syscall.IPPROTO_SCTP { - switch m.Header.Type { - case SCTP_CMSG_SNDRCV: - return (*SndRcvInfo)(unsafe.Pointer(&m.Data[0])), nil - } - } - } - return nil, nil -} - -func (c *SCTPConn) SCTPRead(b []byte) (int, *SndRcvInfo, error) { - oob := make([]byte, 254) - for { - n, oobn, recvflags, _, err := syscall.Recvmsg(c.fd(), b, oob, 0) - if err != nil { - return n, nil, err - } - - if n == 0 && oobn == 0 { - return 0, nil, io.EOF - } - - if recvflags&MSG_NOTIFICATION > 0 && c.notificationHandler != nil { - if err := c.notificationHandler(b[:n]); err != nil { - return 0, nil, err - } - } else { - var info *SndRcvInfo - if oobn > 0 { - info, err = parseSndRcvInfo(oob[:oobn]) - } - return n, info, err - } - } -} - -func (c *SCTPConn) Close() error { - if c != nil { - fd := atomic.SwapInt32(&c._fd, -1) - if fd > 0 { - info := &SndRcvInfo{ - Flags: SCTP_EOF, - } - c.SCTPWrite(nil, info) - syscall.Shutdown(int(fd), syscall.SHUT_RDWR) - return syscall.Close(int(fd)) - } - } - return syscall.EBADF -} - -func (c *SCTPConn) SetWriteBuffer(bytes int) error { - return syscall.SetsockoptInt(c.fd(), syscall.SOL_SOCKET, syscall.SO_SNDBUF, bytes) -} - -func (c *SCTPConn) GetWriteBuffer() (int, error) { - return syscall.GetsockoptInt(c.fd(), syscall.SOL_SOCKET, syscall.SO_SNDBUF) -} - -func (c *SCTPConn) SetReadBuffer(bytes int) error { - return syscall.SetsockoptInt(c.fd(), syscall.SOL_SOCKET, syscall.SO_RCVBUF, bytes) -} - -func (c *SCTPConn) GetReadBuffer() (int, error) { - return syscall.GetsockoptInt(c.fd(), syscall.SOL_SOCKET, syscall.SO_RCVBUF) -} - -// ListenSCTP - start listener on specified address/port -func ListenSCTP(net string, laddr *SCTPAddr) (*SCTPListener, error) { - 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) { - return listenSCTPExtConfig(network, laddr, options, nil) -} - -// listenSCTPExtConfig - start listener on specified address/port with given SCTP options and socket configuration -func listenSCTPExtConfig(network string, laddr *SCTPAddr, options InitMsg, control func(network, address string, c syscall.RawConn) error) (*SCTPListener, error) { - af, ipv6only := favoriteAddrFamily(network, laddr, nil, "listen") - sock, err := syscall.Socket( - af, - syscall.SOCK_STREAM, - syscall.IPPROTO_SCTP, - ) - if err != nil { - return nil, err - } - - // close socket on error - defer func() { - if err != nil { - syscall.Close(sock) - } - }() - if err = setDefaultSockopts(sock, af, ipv6only); err != nil { - return nil, err - } - if control != nil { - rc := rawConn{sockfd: sock} - if err = control(network, laddr.String(), rc); 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 - } - } - err = syscall.Listen(sock, syscall.SOMAXCONN) - if err != nil { - return nil, err - } - return &SCTPListener{ - fd: sock, - }, nil -} - -// 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) { - 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) { - return dialSCTPExtConfig(network, laddr, raddr, options, nil) -} - -// dialSCTPExtConfig - same as DialSCTP but with given SCTP options and socket configuration -func dialSCTPExtConfig(network string, laddr, raddr *SCTPAddr, options InitMsg, control func(network, address string, c syscall.RawConn) error) (*SCTPConn, error) { - af, ipv6only := favoriteAddrFamily(network, laddr, raddr, "dial") - sock, err := syscall.Socket( - af, - syscall.SOCK_STREAM, - syscall.IPPROTO_SCTP, - ) - if err != nil { - return nil, err - } - - // close socket on error - defer func() { - if err != nil { - syscall.Close(sock) - } - }() - if err = setDefaultSockopts(sock, af, ipv6only); err != nil { - return nil, err - } - if control != nil { - rc := rawConn{sockfd: sock} - if err = control(network, laddr.String(), rc); 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 - } - } - _, err = SCTPConnect(sock, raddr) - if err != nil { - return nil, err - } - return NewSCTPConn(sock, nil), nil -} |