/*
* Created on Nov 9, 2004
*
* To change the template for this generated file go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
package de.desy.tine.server.connections;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import de.desy.tine.definitions.TErrorList;
import de.desy.tine.definitions.TFormat;
import de.desy.tine.definitions.TTransport;
import de.desy.tine.server.logger.MsgLog;
import de.desy.tine.stringUtils.StringToBytes;
import de.desy.tine.structUtils.TStructBase;
import de.desy.tine.structUtils.TStructDescription;
import de.desy.tine.structUtils.TStructRegistry;
/**
* \internal
*
* @author duval
*/
public class TClient extends TStructBase
{
static private int getSubNetBitShift(String maskbits)
{
int shft = 0;
try
{
shft = 32 - Integer.parseInt(maskbits);
if (shft < 0 || shft > 16) shft = 0;
}
catch (Exception ignore) {}; // ignore parsing or any other exception
return shft;
}
static private String getSubNetByteAsString(int b)
{
return ""+((b+256)%256);
}
static public boolean isSubNet(int mask,byte[] tgt,byte[] src)
{
int i, k, bit, nb = mask/8, nr = mask%8;
for (i=0; i<nb; i++)
{ /* these bytes must match */
if (tgt[i] != src[i]) return false;
}
for (k=0; k<nr; k++)
{ /* these bits must match */
bit = (1 << (7-k));
if ((tgt[i] & bit) != (src[i] & bit)) return false;
}
return true;
}
public boolean isMemberControlNets(LinkedList<TNetAcl> nets)
{
if (nets == null || nets.size() == 0) return true; // everyone is !
// check vs subnet, vs specified address ...
byte[] tgt = IPaddress.getAddress();
TNetAcl netAcl;
Iterator<TNetAcl> it = nets.iterator();
while (it.hasNext())
{
netAcl = it.next();
if (isSubNet(netAcl.getMask(),netAcl.getRawAddress(),tgt)) return true;
}
return false;
}
public boolean isMemberUsersList(LinkedList<String> usrs)
{
if (usrs == null || usrs.size() == 0) return true; // everyone is !
if (usrs.contains(userName.toUpperCase())) return true;
return false;
}
public static final int ALLOWED_DANGLE_TIME = 20000;
private long timeAppendedToList = 0;
public long getTimeAppendedToList() { return timeAppendedToList; }
public void setTimeAppendedToList(long t) { timeAppendedToList = t; }
// below used in queries ...
public String userName; // 16 char
byte[] IPXaddress = new byte[12]; //[4]; // 4 bytes
byte[] node = new byte[6]; // 6 bytes IPX Immediate Address
short IPfamily = 2;
public short IPport;
public InetAddress IPaddress; // 4 bytes struct sockaddr_in
byte[] IPsine_zero = new byte[8];
public short ncontracts; // number of registrations
public String toString()
{
String s;
s = new String(userName)+" @ "+IPaddress.getHostAddress()+":"+IPport;
s = s.concat(" "+ TTransport.toString(inetProtocol));
s = s.concat(" ("+ncontracts+")");
return s;
}
// NEED the equals to work on the object reference !!!!
// n.b. LocateClientInList() does the address comparisons ...
// public boolean equals(TClient reference)
// {
// if (reference == null) return false;
// if (!reference.IPaddress.equals(IPaddress)) return false;
// if (reference.IPport != IPport) return false;
// return true;
// }
private ArrayList<TContractTable> conLst = new ArrayList<TContractTable>();
private LinkedList<TContractTable> conLstAdd = new LinkedList<TContractTable>();
public void addContract(TContractTable con)
{
synchronized (conLstAdd)
{
conLstAdd.add(con);
}
}
public void rmvContract(TContractTable con)
{
conLst.remove(con);
}
public void clearAddedContracts()
{
synchronized (conLstAdd)
{
conLstAdd.clear();
}
}
public void appendAddedContracts()
{
TContractTable tct = null;
synchronized (conLstAdd)
{
Iterator<TContractTable> li = conLstAdd.iterator();
while (li.hasNext())
{
tct = (TContractTable)li.next();
conLst.add(tct);
}
conLstAdd.clear();
}
}
public boolean hasAddedContracts()
{
return conLstAdd.size() > 0 ? true : false;
}
public TContractTable[] getContractList()
{
TContractTable[] cta = null;
try
{
cta = conLst.toArray(new TContractTable[0]);
}
catch (Exception e)
{
MsgLog.log("getContractList", e.toString(),TErrorList.code_failure,e,1);
};
return cta;
}
public short tineProtocol; // target client protocol level
public short revisionId;
// above used in queries ...
public short inetProtocol; // transport protocol
public int port; // communication port
public OutputStream output; // return communication stream if connected
public Socket sck;
static private TStructDescription myStructDsc; // Export Data structure
static private final int ARRAY_SIZE_HINT = 20;
public static final int nice_query_size = 50;
static
{
initClientStruct();
}
public static TStructDescription getStructDescription()
{
return myStructDsc;
}
private static void initClientStruct()
{
if (TStructRegistry.contains("CLNQS")) return;
myStructDsc = new TStructDescription("CLNQS"); //("XCLNS");
myStructDsc.beginDefinition();
myStructDsc.addField("username",TFormat.CF_TEXT, 16);
myStructDsc.addField("ipxAddr",TFormat.CF_BYTE, 12);
myStructDsc.addField("ipxNode",TFormat.CF_BYTE, 6);
myStructDsc.addField("ipFamily",TFormat.CF_SHORT, 1);
myStructDsc.addField("ipPort",TFormat.CF_SHORT, 1);
myStructDsc.addField("ipAddr",TFormat.CF_BYTE, 4);
myStructDsc.addField("ipZero",TFormat.CF_BYTE, 8);
myStructDsc.addField("numContracts", TFormat.CF_SHORT, 1);
myStructDsc.addField("transport", TFormat.CF_SHORT, 1);
myStructDsc.setArraySize(ARRAY_SIZE_HINT);
myStructDsc.endDefinition();
TStructRegistry.add(myStructDsc);
}
public void writeData(DataOutput dout) throws IOException
{
dout.write(StringToBytes.stringToFixedBytes(userName, 16));
dout.write(IPXaddress);
dout.write(node);
dout.writeShort(IPfamily);
dout.writeShort(port);
// TODO unsure if bytes have to be swapped (writeInt?)
// FIXME Trouble with IPV6? (6 Bytes)
dout.write(IPaddress.getAddress(), 0, 4);
dout.write(IPsine_zero);
dout.writeShort(ncontracts);
dout.writeShort(tineProtocol);
}
/*
* (non-Javadoc)
*
* @see de.desy.tine.client.TStructIfc#readData(java.io.DataInput)
*/
public void readData(DataInput din) throws IOException
{
// FIXME Not implemented
}
}