package com.limegroup.gnutella.messages;
import com.limegroup.gnutella.ByteOrder;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.LinkedList;
import com.limegroup.gnutella.ErrorService;
import com.limegroup.gnutella.RouterService;
import com.limegroup.gnutella.GUID;
import com.limegroup.gnutella.UDPService;
import com.limegroup.gnutella.settings.ApplicationSettings;
import com.limegroup.gnutella.settings.ConnectionSettings;
import com.limegroup.gnutella.util.DataUtils;
import com.limegroup.gnutella.util.NameValue;
/**
* A Gnutella bye message.
*/
public class ByeRequest extends Message {
private short _code=0;
private String _message=null;
private byte[] payload = null;
// normal
public static final byte[] EXIT_NORMAL = {(byte)0x00,(byte)0xC8}; //200
public static final byte[] EXPLICIT_EXIT = {(byte)0x00,(byte)0xC9}; //201
//client fault
public static final byte[] BIG_PACKET = {(byte)0x01, (byte)0x90}; //400
public static final byte[] DUPLICATE = {(byte)0x01, (byte)0x91}; //401
public static final byte[] IMPROPER_QUERY = {(byte)0x01, (byte)0x92}; //402
public static final byte[] LONG_LIVED = {(byte)0x01, (byte)0x93}; //403
public static final byte[] UNKNOWN_MSG = {(byte)0x01, (byte)0x94}; //404
public static final byte[] TIMEOUT = {(byte)0x01, (byte)0x95}; //405
public static final byte[] PONG_FAIL = {(byte)0x01, (byte)0x96}; //406
public static final byte[] MOOCHER = {(byte)0x01, (byte)0x97}; //407
//servent internal error
public static final byte[] BAD_ERROR = {(byte)0x01, (byte)0xF4}; //500
public static final byte[] DESYNC = {(byte)0x01, (byte)0xF5}; //501
public static final byte[] FULL_QUEUE = {(byte)0x01, (byte)0xF6}; //502
/////////////////Constructors for incoming messages/////////////////
/**
* Creates a normal ping from data read on the network
* A Bye packet MUST be sent with TTL=1 (to avoid accidental propagation
* by an unaware servent), and hops=0 (of course).
*/
public ByeRequest(byte[] guid, byte[] payload) {
super(guid, Message.F_BYE, (byte)1, (byte)0, payload.length);
_code = ByteOrder.beb2short(payload, 0);
if( payload.length >2 )
_message = new String(payload,2,(payload.length-2));
this.payload = payload;
}
public static byte[] makePayload(String errorString, byte[] code) {
byte[] errorArray = errorString.getBytes();
byte[] byePayload = new byte[code.length+errorArray.length];
System.arraycopy(code,0,byePayload,0,code.length);
System.arraycopy(errorArray,0,byePayload,code.length,errorArray.length);
return byePayload;
}
public ByeRequest(byte[] guid) {
super(guid, Message.F_BYE, (byte)1, (byte)0, 0);
}
// inherit doc comment
public void recordDrop() {
// maybe we should implement enum style so that we won't dup code
// when add a new type of message
//DroppedSentMessageStatHandler.TCP_PING_REQUESTS.addMessage(this);
}
public String toString() {
return "ByeRequest("+super.toString()+")";
}
// this is try to strip GGEP
public Message stripExtendedPayload() {
return this;
}
protected void writePayload(OutputStream out) throws IOException {
if(payload != null) {
out.write(payload);
}
// the Bye is still written even if there's no payload
//SentMessageStatHandler.TCP_PING_REQUESTS.addMessage(this);
//Do nothing...there is no payload!
}
}