ztip.go (2174B)
1 package main 2 3 import ( 4 "io" 5 "log" 6 "net" 7 "time" 8 9 sam3 "github.com/go-i2p/go-sam-go" 10 ) 11 12 type Node struct { 13 identity string 14 groups []string 15 } 16 17 type Forward struct { 18 Name string 19 KeyFile string 20 LocalAddr net.Addr 21 } 22 23 func main() { 24 samAddr := "127.0.0.1:7656" 25 log.Println("Connecting to SAM server:", samAddr) 26 sam, err := sam3.NewSAM(samAddr) 27 if err != nil { 28 log.Fatal(err) 29 } 30 31 forwards := []Forward{ 32 { 33 Name: "navidrome", 34 KeyFile: "navidrome.dat", 35 LocalAddr: &net.TCPAddr{IP: net.ParseIP("192.168.0.3"), Port: 4533}, 36 }, 37 { 38 Name: "http8080", 39 KeyFile: "http8080.dat", 40 LocalAddr: &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: 8080}, 41 }, 42 } 43 44 startServices(sam, forwards) 45 select {} 46 } 47 48 func startServices(sam *sam3.SAM, forwards []Forward) { 49 for _, fwd := range forwards { 50 keys, err := sam.EnsureKeyfile("keys/" + fwd.KeyFile) 51 if err != nil { 52 log.Printf("Failed to setup keys for %s: %v", fwd.Name, err) 53 continue 54 } 55 56 session, err := sam.NewStreamSession(fwd.Name+time.Now().Format("15:04:05"), keys, sam3.Options_Warning_ZeroHop) 57 if err != nil { 58 log.Printf("Failed to create session for %s: %v", fwd.Name, err) 59 continue 60 } 61 62 go func(target net.Addr, s *sam3.StreamSession) { 63 listener, err := s.Listen() 64 if err != nil { 65 log.Printf("Failed to listen for [%s]:%s", fwd.Name, err) 66 } 67 log.Printf("Service [%s] listening at %s", fwd.Name, keys.Addr().Base32()) 68 69 for { 70 conn, err := listener.Accept() 71 if err != nil { 72 log.Println("accept error:", err) 73 continue 74 } 75 log.Printf("%s wants: %s", conn.RemoteAddr().String(), target) 76 go proxy(conn, target) 77 } 78 }(fwd.LocalAddr, session) 79 } 80 } 81 82 func proxy(i2pConn net.Conn, localAddr net.Addr) { 83 defer i2pConn.Close() 84 85 localConn, err := net.DialTimeout(localAddr.Network(), localAddr.String(), 5*time.Second) 86 if err != nil { 87 log.Printf("ERROR: Local dial failed: %v", err) 88 return 89 } 90 defer localConn.Close() 91 92 errChan := make(chan error, 2) 93 94 cp := func(dst io.Writer, src io.Reader) { 95 _, err := io.Copy(dst, src) 96 errChan <- err 97 } 98 99 go cp(localConn, i2pConn) 100 go cp(i2pConn, localConn) 101 102 <-errChan 103 }