Advertisement
Guest User

Untitled

a guest
Nov 30th, 2015
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.16 KB | None | 0 0
  1. package cachecon
  2.  
  3. import (
  4. "fmt"
  5. "golang.org/x/net/proxy"
  6. "io"
  7. "log"
  8. "net"
  9. )
  10.  
  11. type Config struct {
  12. socksAddr, dstAddr string
  13. }
  14.  
  15. type Server struct {
  16. N int
  17.  
  18. conns chan *net.Conn
  19. }
  20.  
  21. func New(config Config) (*Server, error) {
  22. cache := new(Server)
  23.  
  24. cache.N = 10
  25. cache.conns = make(chan *net.Conn, cache.N)
  26.  
  27. dialer, err := proxy.SOCKS5("tcp", config.socksAddr, nil, &net.Dialer{})
  28. if err != nil {
  29. return nil, err
  30. }
  31.  
  32. for i := 0; i < cache.N; i++ {
  33. conn, err := dialer.Dial("tcp", config.dstAddr)
  34. if err != nil {
  35. log.Printf("Dst connection error: %s", err)
  36. return nil, fmt.Errorf("Can't connect to destination address")
  37. }
  38.  
  39. cache.conns <- &conn
  40. }
  41. return cache, nil
  42. }
  43.  
  44. func (cache Server) Dial() (*net.Conn, error) {
  45. select {
  46. case freeConn := <-cache.conns:
  47. return freeConn, nil
  48. default:
  49. return nil, fmt.Errorf("No free connnections")
  50. }
  51. }
  52.  
  53. func broker(src, dst net.Conn, srcClosed chan struct{}) {
  54. _, err := io.Copy(dst, src)
  55.  
  56. if err != nil {
  57. log.Printf("Copy error: %s", err)
  58. }
  59.  
  60. if err := src.Close(); err != nil {
  61. log.Printf("Close error: %s", err)
  62. }
  63.  
  64. srcClosed <- struct{}{}
  65. }
  66.  
  67. func proxyTcp(serverConn, clientConn *net.TCPConn) {
  68. serverClosed := make(chan struct{}, 1)
  69. clientClosed := make(chan struct{}, 1)
  70.  
  71. go broker(clientConn, serverConn, clientClosed)
  72. go broker(serverConn, clientConn, serverClosed)
  73.  
  74. var waitFor chan struct{}
  75.  
  76. select {
  77. case <-clientClosed:
  78. serverConn.CloseRead()
  79. waitFor = serverClosed
  80. case <-serverClosed:
  81. serverConn.CloseRead()
  82. clientConn.CloseRead()
  83. waitFor = clientClosed
  84. }
  85.  
  86. <-waitFor
  87. }
  88.  
  89. func handleConnection(cacheCon *Server, srcConn *net.Conn) {
  90. dstConn, err := (*cacheCon).Dial()
  91. if err != nil {
  92. log.Panic(err)
  93. }
  94.  
  95. src, okSrc := (*srcConn).(*net.TCPConn)
  96. dst, okDst := (*dstConn).(*net.TCPConn)
  97.  
  98. if !okSrc || !okDst {
  99. log.Panic()
  100. }
  101.  
  102. proxyTcp(dst, src)
  103. }
  104.  
  105. func (cacheCon *Server) Serve(ln net.Listener) {
  106. for {
  107. conn, err := ln.Accept()
  108. if err != nil {
  109. log.Panic(err)
  110. break
  111. }
  112. go handleConnection(cacheCon, &conn)
  113. }
  114. }
  115.  
  116. func (cacheCon *Server) ListenAndServe(servePort string) error {
  117. ln, err := net.Listen("tcp", servePort)
  118. if err != nil {
  119. return err
  120. }
  121. cacheCon.Serve(ln)
  122. return nil
  123. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement