rawconn.go 1.3 KB

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