rawconn.go 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  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. // +build go1.9
  5. package socket
  6. import (
  7. "errors"
  8. "net"
  9. "os"
  10. "syscall"
  11. )
  12. // A Conn represents a raw connection.
  13. type Conn struct {
  14. network string
  15. c syscall.RawConn
  16. }
  17. // NewConn returns a new raw connection.
  18. func NewConn(c net.Conn) (*Conn, error) {
  19. var err error
  20. var cc Conn
  21. switch c := c.(type) {
  22. case *net.TCPConn:
  23. cc.network = "tcp"
  24. cc.c, err = c.SyscallConn()
  25. case *net.UDPConn:
  26. cc.network = "udp"
  27. cc.c, err = c.SyscallConn()
  28. case *net.IPConn:
  29. cc.network = "ip"
  30. cc.c, err = c.SyscallConn()
  31. default:
  32. return nil, errors.New("unknown connection type")
  33. }
  34. if err != nil {
  35. return nil, err
  36. }
  37. return &cc, nil
  38. }
  39. func (o *Option) get(c *Conn, b []byte) (int, error) {
  40. var operr error
  41. var n int
  42. fn := func(s uintptr) {
  43. n, operr = getsockopt(s, o.Level, o.Name, b)
  44. }
  45. if err := c.c.Control(fn); err != nil {
  46. return 0, err
  47. }
  48. return n, os.NewSyscallError("getsockopt", operr)
  49. }
  50. func (o *Option) set(c *Conn, b []byte) error {
  51. var operr error
  52. fn := func(s uintptr) {
  53. operr = setsockopt(s, o.Level, o.Name, b)
  54. }
  55. if err := c.c.Control(fn); err != nil {
  56. return err
  57. }
  58. return os.NewSyscallError("setsockopt", operr)
  59. }