freedom.go 1.7 KB

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