// Path: src/com/ndtorrent/client/ClientInfo.java
// public interface ClientInfo {
// 
// 	public String getID();
// 
// 	// public void getIP();
// 
// 	public int getPort();
// 
// 	// public void getKey();
// 
// 	public String getStorageLocation();
// 
// 	// public int maxOutgoingConnections();
// 
// 	// public int maxIncomingConnections();
// 
// }


import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketTimeoutException;
import java.net.URI;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Random;
import com.ndtorrent.client.ClientInfo;
package com.ndtorrent.client.tracker;



public final class UdpSession extends Session implements Runnable {

	// Implements the UDP tracker protocol

	static final long CONNECTION_ID = 0x41727101980L;
	static final int ACTION_CONNECT = 0;
	static final int ACTION_ANNOUNCE = 1;
	static final int ACTION_SCRAPE = 2;
	static final int ACTION_ERROR = 3;
	static final int ACTION_ERROR_LE = 0x03000000;

	static final int REQUEST_BODY_LENGTH = 2 * 20 + 3 * 8 + 4 * 4 + 2;
	static final int MAX_REQUEST_LENGTH = 100;
	static final int MAX_RESPONSE_LENGTH = 1500;
	static final int MAX_TIMEOUT = 15 * 8; // use the right factor to adjust it
	static final int DEFAULT_PORT = 80;

	private Thread thread;

	private Random random = new Random();

	private DatagramSocket socket;
	private ByteBuffer request_body;
	private ByteBuffer request = ByteBuffer.allocate(MAX_REQUEST_LENGTH);
	private ByteBuffer response = ByteBuffer.allocate(MAX_RESPONSE_LENGTH);

	private boolean is_timeout;
	private boolean is_connection_error;
	private long updated_at;
	private Event last_event;

	private int timeStep = 1;
	private int transaction_id = -1;
	private long connection_id = -1;
	private long expire_time = 0;

	private URI tracker;

// Path: src/com/ndtorrent/client/ClientInfo.java
// public interface ClientInfo {
// 
// 	public String getID();
// 
// 	// public void getIP();
// 
// 	public int getPort();
// 
// 	// public void getKey();
// 
// 	public String getStorageLocation();
// 
// 	// public int maxOutgoingConnections();
// 
// 	// public int maxIncomingConnections();
// 
// }


// Path: src/com/ndtorrent/client/tracker/UdpSession.java
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketTimeoutException;
import java.net.URI;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Random;
import com.ndtorrent.client.ClientInfo;

package com.ndtorrent.client.tracker;



public final class UdpSession extends Session implements Runnable {

	// Implements the UDP tracker protocol

	static final long CONNECTION_ID = 0x41727101980L;
	static final int ACTION_CONNECT = 0;
	static final int ACTION_ANNOUNCE = 1;
	static final int ACTION_SCRAPE = 2;
	static final int ACTION_ERROR = 3;
	static final int ACTION_ERROR_LE = 0x03000000;

	static final int REQUEST_BODY_LENGTH = 2 * 20 + 3 * 8 + 4 * 4 + 2;
	static final int MAX_REQUEST_LENGTH = 100;
	static final int MAX_RESPONSE_LENGTH = 1500;
	static final int MAX_TIMEOUT = 15 * 8; // use the right factor to adjust it
	static final int DEFAULT_PORT = 80;

	private Thread thread;

	private Random random = new Random();

	private DatagramSocket socket;
	private ByteBuffer request_body;
	private ByteBuffer request = ByteBuffer.allocate(MAX_REQUEST_LENGTH);
	private ByteBuffer response = ByteBuffer.allocate(MAX_RESPONSE_LENGTH);

	private boolean is_timeout;
	private boolean is_connection_error;
	private long updated_at;
	private Event last_event;

	private int timeStep = 1;
	private int transaction_id = -1;
	private long connection_id = -1;
	private long expire_time = 0;

	private URI tracker;

	public UdpSession(String url, ClientInfo client_info, String info_hash) {