예제 #1
0
파일: muxserver.go 프로젝트: huin/artemis
func (srv *Service) negotiateNewMuxConn(conn net.Conn) {
	// Deadline of 10s on mux negotiation.
	if err := conn.SetDeadline(time.Now().Add(10 * time.Second)); err != nil {
		srv.log.Printf("Could not set deadline on incoming mux connection - ignoring: %v", err)
	}

	srv.log.Printf("Got mux client %v, negotiating version", conn.RemoteAddr())
	// Protocol version.
	if err := muxcommon.ReadCheckVersion(conn); err != nil {
		conn.Close()
		srv.log.Printf("Error checking mux client version: %v", err)
		return
	}
	if err := muxcommon.SendVersion(conn); err != nil {
		conn.Close()
		srv.log.Printf("Error sending version: %v", err)
		return
	}

	// TODO: Authenticate connection before handing to muxMatcher.

	srv.log.Print("Setting up compression")
	// Set up compression on the data flowing from mux client to mux server.
	compConnRead, err := zlib.NewReader(conn)
	if err != nil {
		conn.Close()
		srv.log.Printf("Failed to initiate reading of compressed data on incoming mux connection: %v", err)
		return
	}

	// Negotiation complete.
	conn.SetDeadline(time.Time{})

	srv.log.Printf("New mux client connected from %v", conn.RemoteAddr())
	srv.newMuxConn <- frames.NewClient(&netutil.ConnWrapper{
		Reader:         compConnRead,
		Writer:         conn,
		UnderlyingConn: conn,
		ReadCloser:     compConnRead,
	})
}
예제 #2
0
파일: muxclient.go 프로젝트: huin/artemis
func (srv *Service) SetConfig(cfg *services.MuxClientConfig) error {
	srv.lock.Lock()
	defer srv.lock.Unlock()

	if cfg.MuxAddr != srv.cfg.MuxAddr {
		var l net.Listener
		var err error
		if cfg.MuxAddr != "" {
			var conn net.Conn
			if conn, err = net.Dial("tcp", cfg.MuxAddr); err != nil {
				return err
			}

			srv.log.Printf("Connected to mux server %v, negotiating version", conn.RemoteAddr())
			// Protocol version.
			muxcommon.SendVersion(conn)
			if err = muxcommon.ReadCheckVersion(conn); err != nil {
				conn.Close()
				return err
			}

			// TODO: Authenticate connection.

			srv.log.Printf("Setting up compression")
			// Set up compression on the data flowing from the mux client to the mux
			// server. Apply a FlushingWriter as well to flush data periodically.
			w, err := zlib.NewWriterLevel(conn, zlib.BestSpeed)
			if err != nil {
				conn.Close()
				return err
			}
			// Flush the writer to send headers so that the server knows that the
			// compressed connection is good.
			w.Flush()

			// TODO: Should the interval be configurable?
			compConnWrite := muxcommon.NewFlushingWriter(w, 50*time.Millisecond)

			wrappedConn := &netutil.ConnWrapper{
				Reader:         conn,
				Writer:         compConnWrite,
				UnderlyingConn: conn,
				WriteCloser:    compConnWrite,
			}

			log.Printf("Waiting for incoming muxed connections")
			if l, err = frames.Listen(wrappedConn); err != nil {
				conn.Close()
				return err
			}
		}

		if srv.listener != nil {
			srv.listener.Close()
		}
		srv.listener = l

		if srv.listener != nil {
			go srv.handleListener(srv.manager, srv.listener, cfg.ArtemisServerAddr)
		}
	}

	srv.cfg = *cfg

	return nil
}