示例#1
0
// Generic connection handler
//
// This redelegates to more specific proxy handlers that contain the
// main proxy loop logic.
func handleConnection(cConn net.Conn, serverAddr string) {
	var err error

	// Log disconnections
	defer func() {
		if err != nil && err != io.EOF {
			fmt.Printf("Session exits with error: %v\n", err)
		} else {
			fmt.Printf("Session exits cleanly\n")
		}
	}()

	defer cConn.Close()

	c := femebe.NewClientMessageStream(
		"Client", newBufWriteCon(cConn))

	unencryptServerConn, err := autoDial(serverAddr)
	if err != nil {
		fmt.Printf("Could not connect to server: %v\n", err)
	}

	tlsConf := tls.Config{}
	tlsConf.InsecureSkipVerify = true

	sConn, err := femebe.NegotiateTLS(
		unencryptServerConn, "prefer", &tlsConf)
	if err != nil {
		fmt.Printf("Could not negotiate TLS: %v\n", err)
	}

	s := femebe.NewServerMessageStream("Server", newBufWriteCon(sConn))
	if err != nil {
		fmt.Printf("Could not initialize connection to server: %v\n", err)
	}

	done := make(chan error)
	NewSimpleProxySession(done, &ProxyPair{c, cConn},
		&ProxyPair{s, sConn}).start()

	// Both sides must exit to finish
	_ = <-done
	_ = <-done
}
func logWorker(die dieCh, rwc io.ReadWriteCloser, cfg logplexc.Config,
	sr *serveRecord) {
	var err error
	stream := femebe.NewServerMessageStream("", rwc)

	var exit exitFn
	exit = func(args ...interface{}) {
		if len(args) == 1 {
			log.Printf("Disconnect client: %v", args[0])
		} else if len(args) > 1 {
			if s, ok := args[0].(string); ok {
				log.Printf(s, args[1:]...)
			} else {
				// Not an intended use case, but do
				// one's best to print something.
				log.Printf("Got a malformed exit: %v", args)
			}
		}

		panic(&exit)
	}

	// Recovers from panic and exits in an orderly manner if (and
	// only if) exit() is called; otherwise propagate the panic
	// normally.
	defer func() {
		rwc.Close()

		// &exit is used as a sentinel value.
		if r := recover(); r != nil && r != &exit {
			panic(r)
		}
	}()

	var msgInit msgInit
	msgInit = func(m *femebe.Message, exit exitFn) {
		err = stream.Next(m)
		if err == io.EOF {
			exit("client disconnects")
		} else if err != nil {
			exit("could not read next message: %v", err)
		}
	}

	// Protocol start-up; packets that are only received once.
	processVerMsg(msgInit, exit)
	ident := processIdentMsg(msgInit, exit)
	log.Printf("client connects with identifier %q", ident)

	// Resolve the identifier to a serve
	if sr.I != ident {
		exit("got unexpected identifier for socket: "+
			"path %s, expected %s, got %s", sr.P, sr.I, ident)
	}

	// Set up client with serve
	cfg.Token = sr.T
	client, err := logplexc.NewClient(&cfg)
	if err != nil {
		exit(err)
	}

	defer client.Close()

	processLogMsg(die, client, msgInit, sr, exit)
}
示例#3
0
文件: dog.go 项目: uhoh-itsmaciek/dog
// Generic connection handler
//
// This redelegates to more specific proxy handlers that contain the
// main proxy loop logic.
func handleConnection(cConn net.Conn, rt *routingTable) {
	var err error

	// Log disconnections
	defer func() {
		if err != nil && err != io.EOF {
			log.Printf("Session exits with error: %v\n", err)
		} else {
			log.Printf("Session exits cleanly\n")
		}
	}()

	defer cConn.Close()

	c := femebe.NewClientMessageStream(
		"Client", newBufWriteCon(cConn))

	// Must interpret Startup and Cancel requests.
	//
	// SSL Negotiation requests not handled for now.
	var firstPacket femebe.Message
	c.Next(&firstPacket)

	// Handle Startup packets
	var sup *pgproto.Startup
	if sup, err = pgproto.ReadStartupMessage(&firstPacket); err != nil {
		log.Print(err)
		return
	}

	var ent *routingEntry
	if ent = rt.rewrite(sup); ent == nil {
		log.Print("Could not route startup packet")
		return
	}

	unencryptServerConn, err := autoDial(ent.addr)
	if err != nil {
		log.Printf("Could not connect to server: %v\n", err)
		return
	}

	tlsConf := tls.Config{}
	tlsConf.InsecureSkipVerify = true

	sConn, err := femebe.NegotiateTLS(
		unencryptServerConn, "prefer", &tlsConf)
	if err != nil {
		log.Printf("Could not negotiate TLS: %v\n", err)
		return
	}

	s := femebe.NewServerMessageStream("Server", newBufWriteCon(sConn))
	if err != nil {
		log.Printf("Could not initialize connection to server: %v\n", err)
		return
	}

	var rewrittenStatupMessage femebe.Message
	sup.FillMessage(&rewrittenStatupMessage)
	err = s.Send(&rewrittenStatupMessage)
	if err != nil {
		return
	}

	err = s.Flush()
	if err != nil {
		return
	}

	done := make(chan error)
	NewSimpleProxySession(done,
		&ProxyPair{c, cConn},
		&ProxyPair{s, sConn}).start()

	// Both sides must exit to finish
	_ = <-done
	_ = <-done
}
示例#4
0
func newTestServerStream(t *testing.T) (*femebe.MessageStream, *inMemRwc) {
	rwc := NewInMemRwc()
	return femebe.NewServerMessageStream("TestServerConn", rwc), rwc
}