freedom.go 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. package freedom
  2. import (
  3. "net"
  4. "sync"
  5. "github.com/v2ray/v2ray-core"
  6. "github.com/v2ray/v2ray-core/common/log"
  7. v2net "github.com/v2ray/v2ray-core/common/net"
  8. )
  9. type FreedomConnection struct {
  10. packet v2net.Packet
  11. }
  12. func NewFreedomConnection(firstPacket v2net.Packet) *FreedomConnection {
  13. return &FreedomConnection{
  14. packet: firstPacket,
  15. }
  16. }
  17. func (vconn *FreedomConnection) Start(ray core.OutboundRay) error {
  18. conn, err := net.Dial(vconn.packet.Destination().Network(), vconn.packet.Destination().Address().String())
  19. log.Info("Freedom: Opening connection to %s", vconn.packet.Destination().String())
  20. if err != nil {
  21. if ray != nil {
  22. close(ray.OutboundOutput())
  23. }
  24. return log.Error("Freedom: Failed to open connection: %s : %v", vconn.packet.Destination().String(), err)
  25. }
  26. input := ray.OutboundInput()
  27. output := ray.OutboundOutput()
  28. var readMutex, writeMutex sync.Mutex
  29. readMutex.Lock()
  30. writeMutex.Lock()
  31. if chunk := vconn.packet.Chunk(); chunk != nil {
  32. conn.Write(chunk)
  33. }
  34. if !vconn.packet.MoreChunks() {
  35. if ray != nil {
  36. close(ray.OutboundOutput())
  37. }
  38. writeMutex.Unlock()
  39. } else {
  40. go dumpInput(conn, input, &writeMutex)
  41. }
  42. go dumpOutput(conn, output, &readMutex)
  43. go func() {
  44. writeMutex.Lock()
  45. if tcpConn, ok := conn.(*net.TCPConn); ok {
  46. tcpConn.CloseWrite()
  47. }
  48. readMutex.Lock()
  49. conn.Close()
  50. }()
  51. return nil
  52. }
  53. func dumpInput(conn net.Conn, input <-chan []byte, finish *sync.Mutex) {
  54. v2net.ChanToWriter(conn, input)
  55. finish.Unlock()
  56. }
  57. func dumpOutput(conn net.Conn, output chan<- []byte, finish *sync.Mutex) {
  58. v2net.ReaderToChan(output, conn)
  59. finish.Unlock()
  60. close(output)
  61. }