You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

68 lines
1.2 KiB

5 years ago
  1. package main
  2. import (
  3. "flag"
  4. "io"
  5. "log"
  6. "net"
  7. )
  8. var listen string
  9. var connect string
  10. func main() {
  11. flag.StringVar(&listen, "listen", ":8000", "listen on ip and port")
  12. flag.StringVar(&connect, "connect", "", "forward to ip and port")
  13. flag.Parse()
  14. // check and parse address
  15. conn, err := net.ResolveTCPAddr("tcp", connect)
  16. if err != nil {
  17. flag.PrintDefaults()
  18. log.Fatal(err)
  19. }
  20. // listen on address
  21. ln, err := net.Listen("tcp", listen)
  22. if err != nil {
  23. flag.PrintDefaults()
  24. log.Fatal(err)
  25. }
  26. log.Printf("listening on %v", ln.Addr())
  27. log.Printf("will connect to %v", conn)
  28. for i := 0; ; i++ {
  29. // accept new connection
  30. c, err := ln.Accept()
  31. if err != nil {
  32. log.Fatal(err)
  33. }
  34. log.Printf("connection %v from %v", i, c.RemoteAddr())
  35. cn, err := net.DialTCP("tcp", nil, conn)
  36. if err != nil {
  37. c.Close()
  38. log.Print(err)
  39. continue
  40. }
  41. go pipe(c, cn, i)
  42. go pipe(cn, c, i)
  43. }
  44. }
  45. func pipe(w io.WriteCloser, r io.ReadCloser, count int) {
  46. n, err := io.Copy(w, r)
  47. r.Close()
  48. w.Close()
  49. log.Printf("connection %v closed, %v bytes", count, n)
  50. opError, ok := err.(*net.OpError)
  51. if err != nil && (!ok || opError.Op != "readfrom") {
  52. log.Printf("warning! %v", err)
  53. }
  54. }