// RegisterTmp create a ephemeral node, and watch it, if node droped then send a SIGQUIT to self. func RegisterTemp(conn *zk.Conn, fpath string, data []byte) error { tpath, err := conn.Create(path.Join(fpath)+"/", data, zk.FlagEphemeral|zk.FlagSequence, zk.WorldACL(zk.PermAll)) if err != nil { log.Error("conn.Create(\"%s\", \"%s\", zk.FlagEphemeral|zk.FlagSequence) error(%v)", fpath, string(data), err) return err } log.Debug("create a zookeeper node:%s", tpath) // watch self go func() { for { log.Info("zk path: \"%s\" set a watch", tpath) exist, _, watch, err := conn.ExistsW(tpath) if err != nil { log.Error("zk.ExistsW(\"%s\") error(%v)", tpath, err) log.Warn("zk path: \"%s\" set watch failed, kill itself", tpath) killSelf() return } if !exist { log.Warn("zk path: \"%s\" not exist, kill itself", tpath) killSelf() return } event := <-watch log.Info("zk path: \"%s\" receive a event %v", tpath, event) } }() return nil }
func (rs *RemoteServer) serveStream(stream net.Conn) { defer stream.Close() start := time.Now() conn, err := net.Dial("tcp", rs.raddr) if err != nil { log.Error("connect to remote error:%v", err) return } defer conn.Close() atomic.AddInt32(&rs.streamCount, 1) streamID := atomic.AddUint64(&rs.streamID, 1) readChan := make(chan int64, 1) writeChan := make(chan int64, 1) var readBytes int64 var writeBytes int64 go pipe(stream, conn, readChan) go pipe(conn, stream, writeChan) for i := 0; i < 2; i++ { select { case readBytes = <-readChan: stream.Close() log.Debug("[#%d] read %d bytes", streamID, readBytes) case writeBytes = <-writeChan: // DON'T call conn.Close, it will trigger an error in pipe. // Just close stream, let the conn copy finished normally log.Debug("[#%d] write %d bytes", streamID, writeBytes) } } log.Info("[#%d] r:%d w:%d t:%v c:%d", streamID, readBytes, writeBytes, time.Now().Sub(start), atomic.LoadInt32(&rs.streamCount)) atomic.AddInt32(&rs.streamCount, -1) }
func (ls *LocalServer) transport(conn net.Conn) { defer conn.Close() start := time.Now() stream, err := ls.openStream() if err != nil { log.Error("open stream for %s error:%v", conn.RemoteAddr().String(), err) return } defer stream.Close() atomic.AddInt32(&ls.streamCount, 1) streamID := atomic.AddUint64(&ls.streamID, 1) readChan := make(chan int64, 1) writeChan := make(chan int64, 1) var readBytes int64 var writeBytes int64 go pipe(conn, stream, readChan) go pipe(stream, conn, writeChan) for i := 0; i < 2; i++ { select { case readBytes = <-readChan: // DON'T call conn.Close, it will trigger an error in pipe. // Just close stream, let the conn copy finished normally log.Debug("[#%d] read %d bytes", streamID, readBytes) case writeBytes = <-writeChan: stream.Close() log.Debug("[#%d] write %d bytes", streamID, writeBytes) } } log.Info("[#%d] r:%d w:%d t:%v c:%d", streamID, readBytes, writeBytes, time.Now().Sub(start), atomic.LoadInt32(&ls.streamCount)) atomic.AddInt32(&ls.streamCount, -1) }
func dialTLS(addr string) (net.Conn, error) { start := time.Now() conn, err := tls.Dial("tcp", addr, &CLIENT_TLS_CONFIG) if err != nil { return nil, err } cs := conn.ConnectionState() log.Info("dialTLS ConnectionState: resume:%v, ciphersuite:0x%02x, cost:%v", cs.DidResume, cs.CipherSuite, time.Now().Sub(start)) return conn, nil }
func main() { flag.BoolVar(&DEBUG, "d", false, "debug mode") mode := flag.String("m", "local", "mode: local or remote") laddr := flag.String("l", "127.0.0.1:9000", "local address") raddr := flag.String("r", "127.0.0.1:9001", "remote address") cert := flag.String("c", "", "certificate (remote)") key := flag.String("k", "", "private key (remote)") tcount := flag.Int("t", 1, "tunnel count (local)") flag.Parse() // go func() { // var addr string // if *mode == "local" { // addr = "localhost:6060" // } else { // addr = "localhost:6061" // } // err := http.ListenAndServe(addr, nil) // if err != nil { // log.Error("pprof error:%v", err) // } // }() if DEBUG { log.AddFilter("stdout", log.DEBUG, log.NewConsoleLogWriter()) } else { log.AddFilter("stdout", log.INFO, log.NewConsoleLogWriter()) } switch *mode { case "local": localServer, err := NewLocalServer(*laddr, *raddr, *tcount) if err != nil { log.Error("NewLocalServer error:%v", err) break } localServer.Serve() case "remote": remoteServer, err := NewRemoteServer(*laddr, *raddr) if err != nil { log.Error("NewRemoteServer error:%v", err) break } remoteServer.Serve(*cert, *key) } log.Info("exit") time.Sleep(2 * time.Second) }