func RejectHandler(conn *WrapedSocket, initial_pkt *mcproto.MCHandShake, e *mcchat.ChatMsg) { if initial_pkt.NextState == 1 { conn.Infof("ping packet") pkt, err := mcproto.ReadPacket(conn) if err != nil { conn.Errorf("Error when reading status request: %s", err.Error()) conn.Close() return } if !pkt.IsStatusRequest() { conn.Errorf("Invalid protocol: no status request.") conn.Close() return } conn.Debugf("status: request") resp := new(mcproto.MCStatusResponse) resp.Description = e resp.Version.Name = "minegate" resp.Version.Protocol = 0 resp_pkt, err := resp.ToRawPacket() if err != nil { conn.Errorf("Unable to make packet: %s", err.Error()) conn.Close() return } _, err = conn.Write(resp_pkt.ToBytes()) if err != nil { log.Errorf("Unable to write response: %s", err.Error()) conn.Close() return } pkt, err = mcproto.ReadPacket(conn) if err != nil { if err != io.EOF { log.Errorf("Unable to read packet: %s", err.Error()) } conn.Close() return } if !pkt.IsStatusPing() { log.Error("Invalid protocol: no status ping.") conn.Close() return } conn.Write(pkt.ToBytes()) // Don't care now. } else { log.Info("login packet") kick_pkt := (*mcproto.MCKick)(e) raw_pkt, err := kick_pkt.ToRawPacket() if err != nil { log.Errorf("Unable to make packet: %s", err.Error()) conn.Close() return } // Don't care now conn.Write(raw_pkt.ToBytes()) } conn.Close() return }
func proxy(conn *WrapedSocket, upstream *Upstream, initial_pkt *mcproto.MCHandShake, ne *PostAcceptEvent) { addr, perr := net.ResolveTCPAddr("tcp", upstream.Server) var err error var upsock *net.TCPConn if perr == nil { upsock, err = net.DialTCP("tcp", nil, addr) } if err != nil || perr != nil { if err == nil { err = perr } log.Errorf("Unable to connect to upstream %s", upstream.Server) RejectHandler(conn, initial_pkt, upstream.ChatMsg) return } upconn := WrapUpstreamSocket(upsock, conn) if initial_pkt.NextState == 1 { // Handle ping here. conn.Debugf("ping proxy") pre := new(PingRequestEvent) pre.NetworkEvent = ne.NetworkEvent pre.Packet = initial_pkt pre.Upstream = upstream PingRequest(pre) if pre.Rejected() { if pre.reason == "" { conn.Warnf("Ping request was rejected.") pre.reason = "Request was rejected by plugin." } else { conn.Warnf("Ping request was rejected: %s", pre.reason) } e := mcchat.NewMsg(pre.reason) e.SetColor(mcchat.RED) e.SetBold(true) RejectHandler(conn, initial_pkt, e) return } init_raw, err := initial_pkt.ToRawPacket() if err != nil { log.Errorf("Unable to encode initial packet: %s", err.Error()) conn.Close() upconn.Close() return } pkt, err := mcproto.ReadPacket(conn) if err != nil { conn.Errorf("Error when reading status request: %s", err.Error()) conn.Close() upconn.Close() return } if !pkt.IsStatusRequest() { conn.Errorf("Invalid protocol: no status request.") conn.Close() upconn.Close() return } _, err = upconn.Write(init_raw.ToBytes()) if err == nil { _, err = upconn.Write(pkt.ToBytes()) } if err != nil { upconn.Errorf("write error: %s", err.Error()) conn.Close() upconn.Close() return } resp_pkt, err := mcproto.ReadPacket(upconn) if err != nil { upconn.Errorf("invalid packet: %s", err.Error()) conn.Close() upconn.Close() return } resp, err := resp_pkt.ToStatusResponse() if err != nil { upconn.Errorf("invalid packet: %s", err.Error()) conn.Close() upconn.Close() return } psre := new(PreStatusResponseEvent) psre.NetworkEvent = ne.NetworkEvent psre.Packet = resp psre.Upstream = upstream PreStatusResponse(psre) resp_pkt, err = resp.ToRawPacket() if err != nil { conn.Errorf("invalid packet: %s", err.Error()) conn.Close() upconn.Close() return } // We can handle ping request, close upstream upconn.Close() _, err = conn.Write(resp_pkt.ToBytes()) if err != nil { conn.Errorf("write error: %s", err.Error()) conn.Close() return } ping_pkt, err := mcproto.ReadPacket(conn) if err != nil || !ping_pkt.IsStatusPing() { if err == nil { err = errors.New("packet is not ping") } conn.Errorf("invalid packet: %s", err.Error()) conn.Close() return } _, err = conn.Write(ping_pkt.ToBytes()) conn.Close() } else { // Handle login here. conn.Debugf("login proxy") login_raw, err := mcproto.ReadPacket(conn) if err != nil { conn.Errorf("Read login packet: %s", err.Error()) conn.Close() return } login_pkt, err := login_raw.ToLogin() if err != nil { conn.Errorf("invalid packet: %s", err.Error()) conn.Close() return } lre := new(LoginRequestEvent) lre.NetworkEvent = ne.NetworkEvent lre.InitPacket = initial_pkt lre.LoginPacket = login_pkt lre.Upstream = upstream LoginRequest(lre) if lre.Rejected() { if lre.reason == "" { conn.Warnf("Ping request was rejected.") lre.reason = "Request was rejected by plugin." } else { conn.Warnf("Ping request was rejected: %s", lre.reason) } e := mcchat.NewMsg(lre.reason) e.SetColor(mcchat.RED) e.SetBold(true) RejectHandler(conn, initial_pkt, e) return } init_raw, err := initial_pkt.ToRawPacket() if err != nil { log.Errorf("Unable to encode initial packet: %s", err.Error()) conn.Close() return } login_raw, err = login_pkt.ToRawPacket() if err != nil { log.Errorf("Unable to encode login packet: %s", err.Error()) conn.Close() return } _, err = upconn.Write(init_raw.ToBytes()) if err == nil { upconn.Write(login_raw.ToBytes()) } if err != nil { upconn.Errorf("write error: %s", err.Error()) } spe := new(StartProxyEvent) spe.Upstream = upstream spe.NetworkEvent = ne.NetworkEvent spe.InitPacket = initial_pkt spe.LoginPacket = login_pkt StartProxy(spe) go PipeIt(conn, upconn) go PipeIt(upconn, conn) } }