github.com/Andyfoo/golang/x/net@v0.0.0-20190901054642-57c1bf301704/internal/socket/rawconn.go (about)

     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  // NewConn returns a new raw connection.
    21  func NewConn(c net.Conn) (*Conn, error) {
    22  	var err error
    23  	var cc Conn
    24  	switch c := c.(type) {
    25  	case *net.TCPConn:
    26  		cc.network = "tcp"
    27  		cc.c, err = c.SyscallConn()
    28  	case *net.UDPConn:
    29  		cc.network = "udp"
    30  		cc.c, err = c.SyscallConn()
    31  	case *net.IPConn:
    32  		cc.network = "ip"
    33  		cc.c, err = c.SyscallConn()
    34  	default:
    35  		return nil, errors.New("unknown connection type")
    36  	}
    37  	if err != nil {
    38  		return nil, err
    39  	}
    40  	return &cc, nil
    41  }
    42  
    43  func (o *Option) get(c *Conn, b []byte) (int, error) {
    44  	var operr error
    45  	var n int
    46  	fn := func(s uintptr) {
    47  		n, operr = getsockopt(s, o.Level, o.Name, b)
    48  	}
    49  	if err := c.c.Control(fn); err != nil {
    50  		return 0, err
    51  	}
    52  	return n, os.NewSyscallError("getsockopt", operr)
    53  }
    54  
    55  func (o *Option) set(c *Conn, b []byte) error {
    56  	var operr error
    57  	fn := func(s uintptr) {
    58  		operr = setsockopt(s, o.Level, o.Name, b)
    59  	}
    60  	if err := c.c.Control(fn); err != nil {
    61  		return err
    62  	}
    63  	return os.NewSyscallError("setsockopt", operr)
    64  }