123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- package conn
- import (
- "bufio"
- "fmt"
- "io"
- "net"
- "sync"
- "github.com/fatedier/frp/utils/log"
- )
- type Listener struct {
- Addr net.Addr
- Conns chan *Conn
- }
- // wait util get one
- func (l *Listener) GetConn() (conn *Conn) {
- conn = <-l.Conns
- return conn
- }
- type Conn struct {
- TcpConn *net.TCPConn
- Reader *bufio.Reader
- }
- func (c *Conn) ConnectServer(host string, port int64) (err error) {
- servertAddr, err := net.ResolveTCPAddr("tcp4", fmt.Sprintf("%s:%d", host, port))
- if err != nil {
- return err
- }
- conn, err := net.DialTCP("tcp", nil, servertAddr)
- if err != nil {
- return err
- }
- c.TcpConn = conn
- c.Reader = bufio.NewReader(c.TcpConn)
- return nil
- }
- func (c *Conn) GetRemoteAddr() (addr string) {
- return c.TcpConn.RemoteAddr().String()
- }
- func (c *Conn) GetLocalAddr() (addr string) {
- return c.TcpConn.LocalAddr().String()
- }
- func (c *Conn) ReadLine() (buff string, err error) {
- buff, err = c.Reader.ReadString('\n')
- return buff, err
- }
- func (c *Conn) Write(content string) (err error) {
- _, err = c.TcpConn.Write([]byte(content))
- return err
- }
- func (c *Conn) Close() {
- if c.TcpConn != nil {
- c.TcpConn.Close()
- }
- }
- func Listen(bindAddr string, bindPort int64) (l *Listener, err error) {
- tcpAddr, err := net.ResolveTCPAddr("tcp4", fmt.Sprintf("%s:%d", bindAddr, bindPort))
- listener, err := net.ListenTCP("tcp", tcpAddr)
- if err != nil {
- return l, err
- }
- l = &Listener{
- Addr: listener.Addr(),
- Conns: make(chan *Conn),
- }
- go func() {
- for {
- conn, err := listener.AcceptTCP()
- if err != nil {
- log.Error("Accept new tcp connection error, %v", err)
- continue
- }
- c := &Conn{
- TcpConn: conn,
- }
- c.Reader = bufio.NewReader(c.TcpConn)
- l.Conns <- c
- }
- }()
- return l, err
- }
- // will block until conn close
- func Join(c1 *Conn, c2 *Conn) {
- var wait sync.WaitGroup
- pipe := func(to *Conn, from *Conn) {
- defer to.Close()
- defer from.Close()
- defer wait.Done()
- var err error
- _, err = io.Copy(to.TcpConn, from.TcpConn)
- if err != nil {
- log.Warn("join conns error, %v", err)
- }
- }
- wait.Add(2)
- go pipe(c1, c2)
- go pipe(c2, c1)
- wait.Wait()
- return
- }
|