conn.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. package tcpprox
  2. import (
  3. "errors"
  4. "io"
  5. "log"
  6. "net"
  7. "sync"
  8. "time"
  9. )
  10. func isValidIP(ip string) bool {
  11. parsedIP := net.ParseIP(ip)
  12. return parsedIP != nil
  13. }
  14. func connCopy(conn1 net.Conn, conn2 net.Conn, wg *sync.WaitGroup, accumulator *int64) {
  15. io.Copy(conn1, conn2)
  16. conn1.Close()
  17. log.Println("[←]", "close the connect at local:["+conn1.LocalAddr().String()+"] and remote:["+conn1.RemoteAddr().String()+"]")
  18. //conn2.Close()
  19. //log.Println("[←]", "close the connect at local:["+conn2.LocalAddr().String()+"] and remote:["+conn2.RemoteAddr().String()+"]")
  20. wg.Done()
  21. }
  22. func forward(conn1 net.Conn, conn2 net.Conn, accumulator *int64) {
  23. log.Printf("[+] start transmit. [%s],[%s] <-> [%s],[%s] \n", conn1.LocalAddr().String(), conn1.RemoteAddr().String(), conn2.LocalAddr().String(), conn2.RemoteAddr().String())
  24. var wg sync.WaitGroup
  25. // wait tow goroutines
  26. wg.Add(2)
  27. go connCopy(conn1, conn2, &wg, accumulator)
  28. go connCopy(conn2, conn1, &wg, accumulator)
  29. //blocking when the wg is locked
  30. wg.Wait()
  31. }
  32. func accept(listener net.Listener) (net.Conn, error) {
  33. conn, err := listener.Accept()
  34. if err != nil {
  35. return nil, err
  36. }
  37. log.Println("[√]", "accept a new client. remote address:["+conn.RemoteAddr().String()+"], local address:["+conn.LocalAddr().String()+"]")
  38. return conn, err
  39. }
  40. func startListener(address string) (net.Listener, error) {
  41. log.Println("[+]", "try to start server on:["+address+"]")
  42. server, err := net.Listen("tcp", address)
  43. if err != nil {
  44. return nil, errors.New("listen address [" + address + "] faild")
  45. }
  46. log.Println("[√]", "start listen at address:["+address+"]")
  47. return server, nil
  48. }
  49. /*
  50. portA -> server
  51. portB -> server
  52. */
  53. func (c *ProxyRelayConfig) Port2port(port1 string, port2 string, stopChan chan bool) error {
  54. listen1, err := startListener("0.0.0.0:" + port1)
  55. if err != nil {
  56. return err
  57. }
  58. listen2, err := startListener("0.0.0.0:" + port2)
  59. if err != nil {
  60. return err
  61. }
  62. log.Println("[√]", "listen port:", port1, "and", port2, "success. waiting for client...")
  63. c.Running = true
  64. go func() {
  65. <-stopChan
  66. log.Println("[x]", "Received stop signal. Exiting Port to Port forwarder")
  67. c.Running = false
  68. listen1.Close()
  69. listen2.Close()
  70. }()
  71. for {
  72. conn1, err := accept(listen1)
  73. if err != nil {
  74. if !c.Running {
  75. return nil
  76. }
  77. continue
  78. }
  79. conn2, err := accept(listen2)
  80. if err != nil {
  81. if !c.Running {
  82. return nil
  83. }
  84. continue
  85. }
  86. if conn1 == nil || conn2 == nil {
  87. log.Println("[x]", "accept client faild. retry in ", c.Timeout, " seconds. ")
  88. time.Sleep(time.Duration(c.Timeout) * time.Second)
  89. continue
  90. }
  91. forward(conn1, conn2, &c.accumulatedByteTransfered)
  92. }
  93. }
  94. /*
  95. portA -> server
  96. server -> portB
  97. */
  98. func (c *ProxyRelayConfig) Port2host(allowPort string, targetAddress string, stopChan chan bool) error {
  99. server, err := startListener("0.0.0.0:" + allowPort)
  100. if err != nil {
  101. return err
  102. }
  103. //Start stop handler
  104. go func() {
  105. <-stopChan
  106. log.Println("[x]", "Received stop signal. Exiting Port to Host forwarder")
  107. c.Running = false
  108. server.Close()
  109. }()
  110. //Start blocking loop for accepting connections
  111. for {
  112. conn, err := accept(server)
  113. if conn == nil || err != nil {
  114. if !c.Running {
  115. //Terminate by stop chan. Exit listener loop
  116. return nil
  117. }
  118. //Connection error. Retry
  119. continue
  120. }
  121. go func(targetAddress string) {
  122. log.Println("[+]", "start connect host:["+targetAddress+"]")
  123. target, err := net.Dial("tcp", targetAddress)
  124. if err != nil {
  125. // temporarily unavailable, don't use fatal.
  126. log.Println("[x]", "connect target address ["+targetAddress+"] faild. retry in ", c.Timeout, "seconds. ")
  127. conn.Close()
  128. log.Println("[←]", "close the connect at local:["+conn.LocalAddr().String()+"] and remote:["+conn.RemoteAddr().String()+"]")
  129. time.Sleep(time.Duration(c.Timeout) * time.Second)
  130. return
  131. }
  132. log.Println("[→]", "connect target address ["+targetAddress+"] success.")
  133. forward(target, conn, &c.accumulatedByteTransfered)
  134. }(targetAddress)
  135. }
  136. }
  137. /*
  138. server -> portA
  139. server -> portB
  140. */
  141. func (c *ProxyRelayConfig) Host2host(address1, address2 string, stopChan chan bool) error {
  142. c.Running = true
  143. go func() {
  144. <-stopChan
  145. log.Println("[x]", "Received stop signal. Exiting Host to Host forwarder")
  146. c.Running = false
  147. }()
  148. for c.Running {
  149. log.Println("[+]", "try to connect host:["+address1+"] and ["+address2+"]")
  150. var host1, host2 net.Conn
  151. var err error
  152. for {
  153. d := net.Dialer{Timeout: time.Duration(c.Timeout)}
  154. host1, err = d.Dial("tcp", address1)
  155. if err == nil {
  156. log.Println("[→]", "connect ["+address1+"] success.")
  157. break
  158. } else {
  159. log.Println("[x]", "connect target address ["+address1+"] faild. retry in ", c.Timeout, " seconds. ")
  160. time.Sleep(time.Duration(c.Timeout) * time.Second)
  161. }
  162. if !c.Running {
  163. return nil
  164. }
  165. }
  166. for {
  167. d := net.Dialer{Timeout: time.Duration(c.Timeout)}
  168. host2, err = d.Dial("tcp", address2)
  169. if err == nil {
  170. log.Println("[→]", "connect ["+address2+"] success.")
  171. break
  172. } else {
  173. log.Println("[x]", "connect target address ["+address2+"] faild. retry in ", c.Timeout, " seconds. ")
  174. time.Sleep(time.Duration(c.Timeout) * time.Second)
  175. }
  176. if !c.Running {
  177. return nil
  178. }
  179. }
  180. forward(host1, host2, &c.accumulatedByteTransfered)
  181. }
  182. return nil
  183. }