Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem with nbconn.NetConn #1605

Closed
mhkarimi1383 opened this issue May 15, 2023 · 5 comments
Closed

Problem with nbconn.NetConn #1605

mhkarimi1383 opened this issue May 15, 2023 · 5 comments
Labels

Comments

@mhkarimi1383
Copy link

I know that this problem is not fully related to this project, but I need help with my problem

func GetRawConnection() (net.Conn, error) {
	conn, err := writePools[rand.Intn(len(writePools))].Acquire(context.Background())
	if err != nil {
		return nil, err
	}
	return conn.Conn().PgConn().Conn(), nil
}

and use it as a normal TCPConn but I'm getting following error

panic: interface conversion: net.Conn is *nbconn.NetConn, not *net.TCPConn

Also I cannot use nbconn.NetConn since it's in internal module also conn property is not public

here is my code that is code that uses GetRawConnection

func handleClient(cliConn *net.TCPConn) {
	defer cliConn.Close()

	serverConn, err := connection.GetRawConnection()
	if err != nil {
		log.Printf("Failed to connect to server: %s", err)
		return
	}
	defer serverConn.Close()
	fmt.Printf("Type of cliConn: %T\n", cliConn)
	fmt.Printf("Type of serverConn: %T\n", serverConn)
	// Proxy(serverConn.(*net.TCPConn), cliConn)
	Proxy(serverConn.(*net.TCPConn), cliConn)
}

func Proxy(srvConn, cliConn *net.TCPConn) {
	serverClosed := make(chan struct{}, 1)
	clientClosed := make(chan struct{}, 1)
	// backend := pgproto3.NewBackend(cliConn, cliConn)

	// startupMsg, err := backend.ReceiveStartupMessage()
	// if err != nil {
	// 	log.Fatal(err)
	// }
	// backend.SetAuthType(pgproto3.AuthTypeMD5Password)

	// switch startupMsg.(type) {
	// case *pgproto3.StartupMessage:
	//	_, err := cliConn.Write((&pgproto3.AuthenticationMD5Password{
	//		Salt: types.MD5AuthSalt,
	//	}).Encode(nil))
	//	if err != nil {
	//		log.Fatal(err)
	//	}
	//}

	go broker(srvConn, cliConn, clientClosed)
	go broker(cliConn, srvConn, serverClosed)

	var waitFor chan struct{}
	select {
	case <-clientClosed:
		srvConn.SetLinger(0)
		srvConn.CloseRead()
		waitFor = serverClosed
	case <-serverClosed:
		cliConn.CloseRead()
		waitFor = clientClosed
	}

	<-waitFor
}

func broker(dst, src net.Conn, srcClosed chan struct{}) {
	_, err := copyBuffer(dst, src, nil)
	if err != nil {
		log.Printf("Copy error: %s", err)
	}
	if err := src.Close(); err != nil {
		log.Printf("Close error: %s", err)
	}
	srcClosed <- struct{}{}
}

Thanks

@jackc
Copy link
Owner

jackc commented May 15, 2023

I'm not sure exactly what you're trying to but at the very least directly using the underlying net.TCPConn is going to be tricky. For one thing it might be net.UnixConn, and if it is a net.TCPConn then it might have a tls.Conn wrapping it.

But regardless, I think what you can do is to set a custom DialFunc on https://pkg.go.dev/github.com/jackc/pgx/[email protected]/pgconn#Config. You'd need to save the reference somewhere and map it back to the pgx.Conn that was ultimately created. A little messy, but it should be possible.

@mhkarimi1383
Copy link
Author

mhkarimi1383 commented May 16, 2023

Thanks I will check it out
but that copyBuffer is the same as io.Copy
I want to use that just like io.Copy

@mhkarimi1383
Copy link
Author

I need this for my https://github.com/mhkarimi1383/pg_pro project

@hothanhloc68
Copy link

I know that this problem is not fully related to this project, but I need help with my problem

func GetRawConnection() (net.Conn, error) {
	conn, err := writePools[rand.Intn(len(writePools))].Acquire(context.Background())
	if err != nil {
		return nil, err
	}
	return conn.Conn().PgConn().Conn(), nil
}

and use it as a normal TCPConn but I'm getting following error

panic: interface conversion: net.Conn is *nbconn.NetConn, not *net.TCPConn

Also I cannot use nbconn.NetConn since it's in internal module also conn property is not public

here is my code that is code that uses GetRawConnection

func handleClient(cliConn *net.TCPConn) {
	defer cliConn.Close()

	serverConn, err := connection.GetRawConnection()
	if err != nil {
		log.Printf("Failed to connect to server: %s", err)
		return
	}
	defer serverConn.Close()
	fmt.Printf("Type of cliConn: %T\n", cliConn)
	fmt.Printf("Type of serverConn: %T\n", serverConn)
	// Proxy(serverConn.(*net.TCPConn), cliConn)
	Proxy(serverConn.(*net.TCPConn), cliConn)
}

func Proxy(srvConn, cliConn *net.TCPConn) {
	serverClosed := make(chan struct{}, 1)
	clientClosed := make(chan struct{}, 1)
	// backend := pgproto3.NewBackend(cliConn, cliConn)

	// startupMsg, err := backend.ReceiveStartupMessage()
	// if err != nil {
	// 	log.Fatal(err)
	// }
	// backend.SetAuthType(pgproto3.AuthTypeMD5Password)

	// switch startupMsg.(type) {
	// case *pgproto3.StartupMessage:
	//	_, err := cliConn.Write((&pgproto3.AuthenticationMD5Password{
	//		Salt: types.MD5AuthSalt,
	//	}).Encode(nil))
	//	if err != nil {
	//		log.Fatal(err)
	//	}
	//}

	go broker(srvConn, cliConn, clientClosed)
	go broker(cliConn, srvConn, serverClosed)

	var waitFor chan struct{}
	select {
	case <-clientClosed:
		srvConn.SetLinger(0)
		srvConn.CloseRead()
		waitFor = serverClosed
	case <-serverClosed:
		cliConn.CloseRead()
		waitFor = clientClosed
	}

	<-waitFor
}

func broker(dst, src net.Conn, srcClosed chan struct{}) {
	_, err := copyBuffer(dst, src, nil)
	if err != nil {
		log.Printf("Copy error: %s", err)
	}
	if err := src.Close(); err != nil {
		log.Printf("Close error: %s", err)
	}
	srcClosed <- struct{}{}
}

Thanks

@jackc
Copy link
Owner

jackc commented Jan 29, 2024

nbconn.NetConn has been removed from pgx so this should no longer be relevant.

@jackc jackc closed this as completed Jan 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants