Bug fixed:Sometimes the server won't recieved a message but tupdump can catch that.
evilArsh opened this issue · comments
evilArsh commented
In the below function ,when c, err = reuseport.ListenPacket(serverNet, laddr)
was executed,this s.conn
did not execute ReadFrom
method,so when message arrived ,it won't be handled,the client didn't get a response and will throw a transaction is timed out
error.
func ListenUDPAndServe(log *zap.Logger, serverNet, laddr string, u *server.Updater) error {
var (
c net.PacketConn
err error
)
opt := u.Get()
if reuseport.Available() && opt.ReusePort {
c, err = reuseport.ListenPacket(serverNet, laddr)
if err != nil {
// Trying to listen without reuseport.
// Sometimes reuseport.Available() can be true, but for subset
// of interfaces it is not available.
reusePortErr := err
c, err = net.ListenPacket(serverNet, laddr)
if err == nil {
opt.ReusePort = false
log.Warn("failed to use REUSEPORT, falling back to non-reuseport", zap.Error(reusePortErr))
}
}
} else {
c, err = net.ListenPacket(serverNet, laddr)
}
if err != nil {
return err
}
opt.Conn = c
s, err := server.New(opt)
if err != nil {
return err
}
u.Subscribe(s)
return s.Serve()
}
add the below code will fixed it
func (s *Server) Serve() error {
s.start()
// ++++++++++++
if s.reusePort {
go s.worker(s.conn)
}
// +++++++++++++
for i := 0; i < runtime.GOMAXPROCS(-1); i++ {
s.wg.Add(1)
if s.reusePort {
s.log.Debug("reusing port for worker", zap.Int("w", i))
laddr := s.conn.LocalAddr()
conn, err := reuseport.ListenPacket(laddr.Network(), laddr.String())
if err != nil {
s.log.Warn("failed to listen for additional socket")
conn = s.conn
} else {
s.conns = append(s.conns, conn)
}
go s.worker(conn)
} else {
go s.worker(s.conn)
}
}
s.wg.Wait()
return nil
}