OSDN Git Service

new repo
[bytom/vapor.git] / vendor / golang.org / x / net / internal / socket / reflect.go
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 // +build !go1.9
6
7 package socket
8
9 import (
10         "errors"
11         "net"
12         "os"
13         "reflect"
14         "runtime"
15 )
16
17 // A Conn represents a raw connection.
18 type Conn struct {
19         c net.Conn
20 }
21
22 // NewConn returns a new raw connection.
23 func NewConn(c net.Conn) (*Conn, error) {
24         return &Conn{c: c}, nil
25 }
26
27 func (o *Option) get(c *Conn, b []byte) (int, error) {
28         s, err := socketOf(c.c)
29         if err != nil {
30                 return 0, err
31         }
32         n, err := getsockopt(s, o.Level, o.Name, b)
33         return n, os.NewSyscallError("getsockopt", err)
34 }
35
36 func (o *Option) set(c *Conn, b []byte) error {
37         s, err := socketOf(c.c)
38         if err != nil {
39                 return err
40         }
41         return os.NewSyscallError("setsockopt", setsockopt(s, o.Level, o.Name, b))
42 }
43
44 func socketOf(c net.Conn) (uintptr, error) {
45         switch c.(type) {
46         case *net.TCPConn, *net.UDPConn, *net.IPConn:
47                 v := reflect.ValueOf(c)
48                 switch e := v.Elem(); e.Kind() {
49                 case reflect.Struct:
50                         fd := e.FieldByName("conn").FieldByName("fd")
51                         switch e := fd.Elem(); e.Kind() {
52                         case reflect.Struct:
53                                 sysfd := e.FieldByName("sysfd")
54                                 if runtime.GOOS == "windows" {
55                                         return uintptr(sysfd.Uint()), nil
56                                 }
57                                 return uintptr(sysfd.Int()), nil
58                         }
59                 }
60         }
61         return 0, errors.New("invalid type")
62 }