conn.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. // +build !confonly
  2. package encoding
  3. import (
  4. "bytes"
  5. "context"
  6. "io"
  7. "net"
  8. "time"
  9. "google.golang.org/grpc/peer"
  10. )
  11. // GunService is the abstract interface of GunService_TunClient and GunService_TunServer
  12. type GunService interface {
  13. Context() context.Context
  14. Send(*Hunk) error
  15. Recv() (*Hunk, error)
  16. }
  17. // GunConn implements net.Conn for gun tunnel
  18. type GunConn struct {
  19. service GunService
  20. reader io.Reader
  21. over context.CancelFunc
  22. local net.Addr
  23. remote net.Addr
  24. }
  25. // Read implements net.Conn.Read()
  26. func (c *GunConn) Read(b []byte) (n int, err error) {
  27. if c.reader == nil {
  28. h, err := c.service.Recv()
  29. if err != nil {
  30. return 0, newError("unable to read from gun tunnel").Base(err)
  31. }
  32. c.reader = bytes.NewReader(h.Data)
  33. }
  34. n, err = c.reader.Read(b)
  35. if err == io.EOF {
  36. c.reader = nil
  37. return n, nil
  38. }
  39. return n, err
  40. }
  41. // Write implements net.Conn.Write()
  42. func (c *GunConn) Write(b []byte) (n int, err error) {
  43. err = c.service.Send(&Hunk{Data: b})
  44. if err != nil {
  45. return 0, newError("Unable to send data over gun").Base(err)
  46. }
  47. return len(b), nil
  48. }
  49. // Close implements net.Conn.Close()
  50. func (c *GunConn) Close() error {
  51. if c.over != nil {
  52. c.over()
  53. }
  54. return nil
  55. }
  56. // LocalAddr implements net.Conn.LocalAddr()
  57. func (c *GunConn) LocalAddr() net.Addr {
  58. return c.local
  59. }
  60. // RemoteAddr implements net.Conn.RemoteAddr()
  61. func (c *GunConn) RemoteAddr() net.Addr {
  62. return c.remote
  63. }
  64. // SetDeadline implements net.Conn.SetDeadline()
  65. func (*GunConn) SetDeadline(time.Time) error {
  66. return nil
  67. }
  68. // SetReadDeadline implements net.Conn.SetReadDeadline()
  69. func (*GunConn) SetReadDeadline(time.Time) error {
  70. return nil
  71. }
  72. // SetWriteDeadline implements net.Conn.SetWriteDeadline()
  73. func (*GunConn) SetWriteDeadline(time.Time) error {
  74. return nil
  75. }
  76. // NewGunConn creates GunConn which handles gun tunnel
  77. func NewGunConn(service GunService, over context.CancelFunc) *GunConn {
  78. conn := &GunConn{
  79. service: service,
  80. reader: nil,
  81. over: over,
  82. }
  83. conn.local = &net.TCPAddr{
  84. IP: []byte{0, 0, 0, 0},
  85. Port: 0,
  86. }
  87. pr, ok := peer.FromContext(service.Context())
  88. if ok {
  89. conn.remote = pr.Addr
  90. } else {
  91. conn.remote = &net.TCPAddr{
  92. IP: []byte{0, 0, 0, 0},
  93. Port: 0,
  94. }
  95. }
  96. return conn
  97. }