diff --git a/client/visitor.go b/client/visitor.go index 52f4ccd9..ea548298 100644 --- a/client/visitor.go +++ b/client/visitor.go @@ -377,29 +377,33 @@ func (sv *SUDPVisitor) Run() (err error) { func (sv *SUDPVisitor) dispatcher() { xl := xlog.FromContextSafe(sv.ctx) + var ( + visitorConn net.Conn + err error + + firstPacket *msg.UDPPacket + ) + for { - // loop for get frpc to frps tcp conn - // setup worker - // wait worker to finished - // retry or exit - visitorConn, err := sv.getNewVisitorConn() - if err != nil { - // check if proxy is closed - // if checkCloseCh is close, we will return, other case we will continue to reconnect - select { - case <-sv.checkCloseCh: + select { + case firstPacket = <-sv.sendCh: + if firstPacket == nil { xl.Info("frpc sudp visitor proxy is closed") return - default: } + case <-sv.checkCloseCh: + xl.Info("frpc sudp visitor proxy is closed") + return + } - time.Sleep(3 * time.Second) - + visitorConn, err = sv.getNewVisitorConn() + if err != nil { xl.Warn("newVisitorConn to frps error: %v, try to reconnect", err) continue } - sv.worker(visitorConn) + // visitorConn always be closed when worker done. + sv.worker(visitorConn, firstPacket) select { case <-sv.checkCloseCh: @@ -407,9 +411,10 @@ func (sv *SUDPVisitor) dispatcher() { default: } } + } -func (sv *SUDPVisitor) worker(workConn net.Conn) { +func (sv *SUDPVisitor) worker(workConn net.Conn, firstPacket *msg.UDPPacket) { xl := xlog.FromContextSafe(sv.ctx) xl.Debug("starting sudp proxy worker") @@ -463,6 +468,14 @@ func (sv *SUDPVisitor) worker(workConn net.Conn) { }() var errRet error + if firstPacket != nil { + if errRet = msg.WriteMsg(conn, firstPacket); errRet != nil { + xl.Warn("sender goroutine for udp work connection closed: %v", errRet) + return + } + xl.Trace("send udp package to workConn: %s", firstPacket.Content) + } + for { select { case udpMsg, ok := <-sv.sendCh: