package udpproxy import ( "net" "strings" "time" log "github.com/sirupsen/logrus" ) type Session struct { serverConn *net.UDPConn proxyConn *net.UDPConn caddr *net.UDPAddr updateTime time.Time } func newSession(caddr *net.UDPAddr, raddr *net.UDPAddr, proxyConn *net.UDPConn) (*Session, error) { serverConn, err := net.DialUDP("udp", nil, raddr) if err != nil { return nil, err } session := &Session{ serverConn: serverConn, proxyConn: proxyConn, caddr: caddr, updateTime: time.Now(), } go session.listen() return session, nil } func (s *Session) isRconPacket(buf []byte) bool { return string(buf[:8]) == "\xff\xff\xff\xffrcon" } func (s *Session) isResponsePacket(buf []byte) bool { return string(buf[:9]) == "\xff\xff\xff\xffprint" } func (s *Session) listen() error { for { buf := make([]byte, 2048) n, err := s.serverConn.Read(buf) if err != nil { log.Println(err) continue } go s.proxyFrom(buf[:n]) } } func (s *Session) proxyFrom(buf []byte) error { s.updateTime = time.Now() _, err := s.proxyConn.WriteToUDP(buf, s.caddr) if err != nil { log.Println(err) return err } if s.isResponsePacket(buf) { parts := strings.Split(string(buf[10:]), " ") log.Debugf("Response: %s", strings.Join(parts, " ")) } return nil } func (s *Session) proxyTo(buf []byte) error { s.updateTime = time.Now() _, err := s.serverConn.Write(buf) if err != nil { log.Println(err) return err } if s.isRconPacket(buf) { parts := strings.Split(string(buf), " ") log.Infof("From [%s] To [%s] Command: %s", s.caddr.IP.String(), s.serverConn.RemoteAddr().String(), strings.Join(parts[2:], " ")) } return nil }