gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

rawconn.go (2206B)


      1 // Copyright 2017 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 package socket
      6 
      7 import (
      8 	"errors"
      9 	"net"
     10 	"os"
     11 	"syscall"
     12 )
     13 
     14 // A Conn represents a raw connection.
     15 type Conn struct {
     16 	network string
     17 	c       syscall.RawConn
     18 }
     19 
     20 // tcpConn is an interface implemented by net.TCPConn.
     21 // It can be used for interface assertions to check if a net.Conn is a TCP connection.
     22 type tcpConn interface {
     23 	SyscallConn() (syscall.RawConn, error)
     24 	SetLinger(int) error
     25 }
     26 
     27 var _ tcpConn = (*net.TCPConn)(nil)
     28 
     29 // udpConn is an interface implemented by net.UDPConn.
     30 // It can be used for interface assertions to check if a net.Conn is a UDP connection.
     31 type udpConn interface {
     32 	SyscallConn() (syscall.RawConn, error)
     33 	ReadMsgUDP(b, oob []byte) (n, oobn, flags int, addr *net.UDPAddr, err error)
     34 }
     35 
     36 var _ udpConn = (*net.UDPConn)(nil)
     37 
     38 // ipConn is an interface implemented by net.IPConn.
     39 // It can be used for interface assertions to check if a net.Conn is an IP connection.
     40 type ipConn interface {
     41 	SyscallConn() (syscall.RawConn, error)
     42 	ReadMsgIP(b, oob []byte) (n, oobn, flags int, addr *net.IPAddr, err error)
     43 }
     44 
     45 var _ ipConn = (*net.IPConn)(nil)
     46 
     47 // NewConn returns a new raw connection.
     48 func NewConn(c net.Conn) (*Conn, error) {
     49 	var err error
     50 	var cc Conn
     51 	switch c := c.(type) {
     52 	case tcpConn:
     53 		cc.network = "tcp"
     54 		cc.c, err = c.SyscallConn()
     55 	case udpConn:
     56 		cc.network = "udp"
     57 		cc.c, err = c.SyscallConn()
     58 	case ipConn:
     59 		cc.network = "ip"
     60 		cc.c, err = c.SyscallConn()
     61 	default:
     62 		return nil, errors.New("unknown connection type")
     63 	}
     64 	if err != nil {
     65 		return nil, err
     66 	}
     67 	return &cc, nil
     68 }
     69 
     70 func (o *Option) get(c *Conn, b []byte) (int, error) {
     71 	var operr error
     72 	var n int
     73 	fn := func(s uintptr) {
     74 		n, operr = getsockopt(s, o.Level, o.Name, b)
     75 	}
     76 	if err := c.c.Control(fn); err != nil {
     77 		return 0, err
     78 	}
     79 	return n, os.NewSyscallError("getsockopt", operr)
     80 }
     81 
     82 func (o *Option) set(c *Conn, b []byte) error {
     83 	var operr error
     84 	fn := func(s uintptr) {
     85 		operr = setsockopt(s, o.Level, o.Name, b)
     86 	}
     87 	if err := c.c.Control(fn); err != nil {
     88 		return err
     89 	}
     90 	return os.NewSyscallError("setsockopt", operr)
     91 }