/**
* SLPv2 message parser (protocol stack)
* Use separate get-methods to obtain each field after parsing
*
*/
package eu.artemis.shield.discovery.slpdaemon.impl;
import java.io.*;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.Signature;
import java.security.interfaces.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import java.util.*;
import java.net.InetAddress;
import java.security.InvalidKeyException;
import java.security.SignatureException;
//import eu.artemis.shield.discovery.pdm_slp.sdc.slpapi.ServiceLocationAttribute;
public class slpMsgParser {
private static boolean WRITE_LOG_ON_FILE = false;
da daf;
Database database;
int version, func_id, packet_len, slp_flag, ext_offset, xid,
ecode, lifetime,attrlength;
String ltag, scope, attr, pred, spi, tag, type, prlist, url,_attr1;
String attrList, typeList, urlList;
int daBootTS; // DA boot timestamp
int meshFwdID; // in MeshFwd ext.
long versionTS; // version TS from the SA for the update
long arrivalTS; // arrival TS at the DA for the update
String acceptDA; // the accept DA for the update
long acceptTS; // the accept TS for the update
Vector atsList, adaList; // used in DataRqst
Vector ssExtList; // used in SrvRqst
boolean hasSelectExt; // whether has Select extensions
Vector urlVector, attrVector; // used in AttrList extension
boolean hasAttrListExt; // whether has AttrList extensions
int totalMatch; // number of matches before selection
Vector matchedEntry; // matched entries in database
int etrpType;
PrintStream ps;
long after, before;
InetAddress daTCPServeria;
RSAPublicKey _publicKey;
/*
slpMsgParser(da daf) throws Exception { // for DA
init(daf);
}
*/
slpMsgParser(da daf, InetAddress ia) throws Exception { // for DA
init(daf);
daTCPServeria = ia;
url = ia.getHostAddress();
da.appendDebug("slpMsgParser::slpMsgParser->ia.hostAdrr ="+ ia.getHostAddress());
}
public InetAddress getTCPServerInetAddress()
{
return daTCPServeria;
}
private void init(da daf) throws Exception { // for DA
this.daf = daf;
database = daf.getDatabase();
atsList = new Vector(10);
adaList = new Vector(10);
ssExtList = new Vector(10);
urlVector = new Vector(10);
attrVector = new Vector(10);
if (WRITE_LOG_ON_FILE) {
File f = new File(".","logTest.txt");
FileOutputStream fos = new FileOutputStream(f);
ps = new PrintStream(fos);
}
}
slpMsgParser() { // for UA/SA
ssExtList = new Vector(10);
urlVector = new Vector(10);
attrVector = new Vector(10);
}
/**
* SLP common message header, not including language tag
*+--------------+-----------------+----------------------------------+
*| Version | Function-ID | Length |
*+--------------+-+-+-+-----------+---------------+------------------+
*| Length cont. |O|F|R| Reserved | Next Ext. Offset |
*+--------------+-+-+-+-----------+---------------+------------------+
*| Next Ext. Offset Cont. | XID |
*+--------------------------------+----------------------------------+
*/
public void Header(byte[] buf) { // parse header
int[] ia = { 0 };
version = Util.parseInt(buf, ia, 1); // index=0
func_id = Util.parseInt(buf, ia, 1); // index=1
packet_len = Util.parseInt(buf, ia, 3); // index=2
slp_flag = Util.parseInt(buf, ia, 2); // index=5
ext_offset = Util.parseInt(buf, ia, 3); // index=7
xid = Util.parseInt(buf, ia, 2); // index=10
}
public void LangTag(byte[] buf, int ia[]) { // parse language tag
ltag = Util.parseString(buf, ia);
}
public int getPacketLen() {
return packet_len;
}
public int getFuncID() {
return func_id;
}
public int getFlag() {
return slp_flag;
}
public int getXID() {
return xid;
}
public String getLtag() {
return ltag;
}
public String getURL() {
return url;
}
public String getScope() {
return scope;
}
public String getAttr() {
return attr;
}
public String getAttrList() {
return attrList;
}
public String getTypeList() {
return typeList;
}
public String getUrlList() {
return urlList;
}
public int getEcode() {
return ecode;
}
public int getDaBootTS() {
return daBootTS;
}
public int getMeshFwdID() {
return meshFwdID;
}
public long getVersionTS() {
return versionTS;
}
public String getAcceptDA() {
return acceptDA;
}
public long getAcceptTS() {
return acceptTS;
}
public Vector getAtsList() { // be careful Object CANNOT be
return (Vector) atsList.clone(); // shared between two threads
}
public Vector getAdaList() { // CANNOT be shared!
return (Vector) adaList.clone();
}
public int findTotalMatch() {
if (ssExtList.size() > 0) {
SelectSortExt ss = (SelectSortExt) ssExtList.elementAt(0);
if (ss.getID() == Const.SelectExt) return ss.getBound();
}
return 0;
}
public int getTotalMatch() {
return totalMatch;
}
public int getEtrpType() {
return etrpType;
}
public boolean hasSelectExt() {
return hasSelectExt;
}
public boolean hasAttrListExt() {
return hasAttrListExt;
}
public Vector getMatchedEntry() {
return matchedEntry;
}
public Vector getUrlVector() {
return urlVector;
}
public Vector getAttrVector() {
return attrVector;
}
/**
* parse URL entry, to get the lifetime & URL string
*+---------------+---------------------------------+----------------+
*| Reserved | Lifetime | URL length |
*+---------------+---------------------------------+----------------+
*| URL len cont. | URL (variable length) \
*+---------------+--------------------------------------------------+
*| # of URL auths| Auth. blocks (if any) \
*+------------------------------------------------------------------+
*/
public String parseURL(byte[] buf, int[] ia) {
da.appendDebug("slpMsgParser::parseURL");
ia[0] += 1; // skip one byte for reserved
lifetime = Util.parseInt(buf, ia, 2); // lifetime
url = Util.parseString(buf, ia); // URL
if (Util.parseInt(buf, ia, 1) != 0) {
da.appendDebug("slpMsgParser::parseURL -> URL authentication blocks are present");
}
return url;
}
/**
* service request <#1>
*+----------------------------+---------------------------+
*| length of <PRList> | <PRList> string \
*+----------------------------+---------------------------+
*| length of <service-type> | <service-type> string \
*+----------------------------+---------------------------+
*| length of <scope-list> | <scope-list> string \
*+----------------------------+---------------------------+
*| length of predicate string | service request predicate \
*+----------------------------+---------------------------+
*| length of <SLP SPI> string | <SLP SPI> string \
*+----------------------------+---------------------------+
*/
public byte[] SrvRqst(byte[] buf, int[] ia) {
prlist = Util.parseString(buf, ia); // PRList
type = Util.parseString(buf, ia); // service type
scope = Util.parseString(buf, ia); // scope list
pred = Util.parseString(buf, ia); // predicate
spi = Util.parseString(buf, ia); // SLP SPI string
if (type.equalsIgnoreCase(Const.DAAdvert_Rqst)) return null;
byte[] tmp = database.getMatchedURL(type, scope, pred, ltag, ssExtList, ecode, getFuncID(), null);
totalMatch = database.getTotalMatch();
matchedEntry = database.getMatchedEntry();
if (Const.MESSAGE_LOG_ENABLED && Const.SrvRqst_LOG_ENABLED) da.append("\nINCOMING SRVRQST MESSAGE" +
"\n- Xid = "+ xid +
"\n- PRList = "+ prlist +
"\n- Type = " + type +
"\n- Scope = " + scope +
"\n- Predicate = " + pred +
"\n- SPI = " + spi +
"\n");
return tmp;
}
/**
* secure service request <#13>
*+----------------------------+---------------------------+
*| length of <PRList> | <PRList> string \
*+----------------------------+---------------------------+
*| length of <service-type> | <service-type> string \
*+----------------------------+---------------------------+
*| length of <scope-list> | <scope-list> string \
*+----------------------------+---------------------------+
*| length of predicate string | service request predicate \
*+----------------------------+---------------------------+
*| length of <SLP SPI> string | <SLP SPI> string \
*+----------------+-----------+---------------------------+
*| # of AttrAuths | Attribute Authentication Blocks \
*+----------------+---------------------------------------+
*/
public byte[] SrvRqstAuth(byte[] buf, int[] ia) {
prlist = Util.parseString(buf, ia); // PRList
type = Util.parseString(buf, ia); // service type
scope = Util.parseString(buf, ia); // scope list
pred = Util.parseString(buf, ia); // predicate
spi = Util.parseString(buf, ia); // SLP SPI string
int authBlockNum = Util.parseInt(buf, ia, 1);
da.appendDebug("slpMsgParser::SrvRqstAuth -> " + authBlockNum + " Attribute Authentication Block(s) found");
if(authBlockNum!=0){
AuthBlock(buf,ia,authBlockNum);
}
else ecode=Const.AUTHENTICATION_ABSENT;
if (type.equalsIgnoreCase(Const.DAAdvert_Rqst)) return null;
byte[] tmp = database.getMatchedURL(type, scope, pred, ltag, ssExtList, ecode,getFuncID(), _publicKey);
totalMatch = database.getTotalMatch();
matchedEntry = database.getMatchedEntry();
if (Const.MESSAGE_LOG_ENABLED && Const.SrvRqstAuth_LOG_ENABLED) da.append("\nINCOMING SECURESRVRQST MESSAGE" +
"\n- Xid = "+ xid +
"\n- PRList = "+ prlist +
"\n- Type = " + type +
"\n- Scope = " + scope +
"\n- Predicate = " + pred +
"\n- SPI = " + spi +
"\n");
return tmp;
}
/**
* service reply (reply for service request) <#2>
*+----------------------------+---------------------------+
*| Error Code | URL entry count |
*+----------------------------+---------------------------+
*| <URL entry 1> ... <URL entry N> \
*+----------------------------+---------------------------+
*/
public void SrvReply(byte[] buf, int[] ia) {
ecode = Util.parseInt(buf, ia, 2);
if (Const.MESSAGE_LOG_ENABLED && Const.SrvRply_LOG_ENABLED) da.append("\nINCOMING SRVREPLY MESSAGE" +
"\n- Xid = "+ xid +
"\n- Error Code = " + ecode);
int n = Util.parseInt(buf, ia, 2);
if (Const.MESSAGE_LOG_ENABLED && Const.SrvRply_LOG_ENABLED) da.append("\n- URLs = " + n);
StringBuffer tl = new StringBuffer();
for (int i=0; i<n; i++) {
if (tl.length() > 0) tl.append(",");
String strurl = parseURL(buf, ia);
if (Const.MESSAGE_LOG_ENABLED && Const.SrvRply_LOG_ENABLED) da.append("\n "+ (i+1) +"> " + strurl);
tl.append(url); // URL only, no lifetime
}
urlList = tl.toString();
if (Const.MESSAGE_LOG_ENABLED && Const.SrvRply_LOG_ENABLED) da.append("\n");
}
/**
* service registration <#3>
*+----------------------------------------------------------------+
*| <URL-Entry> \
*+---------------------------------+------------------------------+
*| length of service type string | <service-type> \
*+---------------------------------+------------------------------+
*| length of <scope-list> | <scope-list> \
*+---------------------------------+------------------------------+
*| length of attr-list string | <attr-list> \
*+----------------+----------------+------------------------------+
*| # of AttrAuths | (if present) Attribute Authentication Blocks \
*+----------------+-----------------------------------------------+
* Need to set error code (ecode)
* Extensions have been parsed, so versionTS/acceptDA/acceptTS are known
*/
public void SrvReg(byte[] buf, int[] ia)
{
parseURL(buf, ia); // URL
type = Util.parseString(buf, ia); // service type
scope = Util.parseString(buf, ia); // scope list
attrlength=Util.parseInt(buf, ia, 2); // length of attr-list
ia[0]=ia[0]-2;
attr = Util.parseString(buf, ia); // attribute list
_attr1=attr;
int authBlockNum = Util.parseInt(buf, ia, 1);
da.appendDebug("slpMsgParser::SrvReg -> " + authBlockNum + " Attribute Authentication Block(s) found");
if(authBlockNum!=0)
{
AuthBlock(buf,ia,authBlockNum);
}
else if (authBlockNum==0)
{
if (Const.SERVICE_REGISTRATION_AUTH_REQUIRED)
{
da.appendDebug("> Error: Authentication Absent");
ecode=Const.AUTHENTICATION_ABSENT;
da.displayMessage ("Authentication Block NOT found", Const.EXCLAMATION, "Authentication check");
}
}
if (lifetime < 0) //Lifetime == 0 will be considered VALID and as a service with an INFINITE Lifetime
{
ecode = Const.INVALID_REGISTRATION;
}
else if (!Util.shareString(daf.getScope(), scope, ","))
{
ecode = Const.SCOPE_NOT_SUPPORTED;
}
else
{
if (acceptDA.equalsIgnoreCase(daf.getFQDN()))
{
arrivalTS = acceptTS;
}
else
{
arrivalTS = System.currentTimeMillis();
}
if(ecode==0)
{
ecode = database.addEntry(false, ltag, type, url, lifetime, scope,
attr, slp_flag, versionTS, arrivalTS, acceptDA, acceptTS);
}
}
if (Const.MESSAGE_LOG_ENABLED && Const.SrvReg_LOG_ENABLED)
{
String token = null;
String attribute = null;
StringTokenizer st = new StringTokenizer(attr,",");
attr = "";
while (st.hasMoreTokens())
{
token = st.nextToken();
if (token.startsWith("("))
{
if (token.endsWith(")"))
{
/*
* We have a valid attribute in token, with one value
* (attr_tag=attr_values)
*/
attr += "\n " + token.substring(1,token.length()-1);
}
else
{
/*
* We have the first part of a valid attribute in token, with more than one value
* (attr_tag=attr_values)
*/
attribute = token.substring(1);
}
}
else
{
if (attribute != null)
{
if (token.endsWith(")"))
{
/*
* We have the last part of a valid attribute in token, with more than one value
* (attr_tag=attr_values)
*/
attr += "\n " + attribute + "," + token.substring(0,token.length()-1);
attribute = null;
}
else
{
/*
* We have the N part of a valid attribute in token, with more than one value
* (attr_tag=attr_values)
*/
attribute += "," + token;
}
}
else
{
/*
* We have an attribute in token with no values
* attr_tag
*/
//da.appendDebug("Attribute Name = " + token);
attr += "\n " + token;
}
}
}
da.append("\nINCOMING SRVREG MESSAGE"+
"\n- Xid = "+ xid +
"\n- Type = " + type +
"\n- Scope = " + scope +
"\n- Url = " + url +
"\n- Lifetime = " + lifetime +
"\n- Attribute List = " + attr +
"\n");
}
}
/**
* Authentication Block
*+---------------------------------+------------------------------+
*| Block Structure Descriptor | Authentication Block Length \
*+---------------------------------+------------------------------+
*| Timestamp \
*+---------------------------------+------------------------------+
*| SPI Length | SPI \
*+---------------------------------+------------------------------+
*| SIGNATURE \
*+----------------------------------------------------------------+
*/
public void AuthBlock(byte[] buf,int[] ia,int authblocknum){
for (int i = 1; i <= authblocknum; i++)
{
da.appendDebug("slpMsgParser::SrvReg -> Parsing Authentication Block [" + i + "]");
int BSD = Util.parseInt(buf, ia, 2);
da.appendDebug(" > BSD = " + BSD);
int blockLength = Util.parseInt(buf, ia, 2);
da.appendDebug(" > Block Length = " + blockLength);
int timeStamp = Util.parseInt(buf, ia, 4);
da.appendDebug(" > Time Stamp = " + (new Date((long)timeStamp*1000)).toString());
/*Estrazione chiave Pubblica*/
ia[0]=ia[0]+2;
byte[] _spi=new byte[162];
for(int k=0; k < 162; k++)
{
_spi[k] = buf[ia[0]+k];
}
ia[0]=ia[0]+162;
try{
X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(_spi);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
_publicKey =(RSAPublicKey) keyFactory.generatePublic(pubKeySpec);
da.append(" > SPI = "+_publicKey.toString());
}catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (InvalidKeySpecException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
/*Signature*/
int signLength = blockLength - 10 - _spi.length;
byte[] _sign = new byte[signLength];
for (int j = 0; j < signLength; j++)
{
_sign[j] = buf[ia[0]+j];
}
da.append(" > SIGN = "+ _sign);
/*Sign Verify*/
if(func_id==Const.SrvReg)
{
try{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(bos);
dos.writeShort(_spi.length);
dos.write(_spi);
dos.writeShort((short) attrlength);
String token1 = null;
StringTokenizer st1 = new StringTokenizer(_attr1,",");
_attr1="";
while (st1.hasMoreTokens())
{
token1 = st1.nextToken();
if (token1.startsWith("("))
{
if (token1.endsWith(")"))
{
int indexuguale= token1.indexOf("=");
dos.write("(".getBytes());
dos.write(token1.substring(1,indexuguale).getBytes());
dos.write("=".getBytes());
dos.write(token1.substring(indexuguale+1,token1.length()-1).getBytes());
dos.write(")".getBytes());
}
}
else
{
dos.write(token1.getBytes());
}
}
dos.writeInt(timeStamp);
dos.write(getURL().getBytes());
byte[] data=bos.toByteArray();
Signature signature = Signature.getInstance("SHA1withRSA");
signature.initVerify(_publicKey);
signature.update(data);
boolean verify=signature.verify(_sign);
if(verify){
da.append("> Athentication Executed Correctly");
}
else{
da.append("> Error: Authentication Failed");
da.displayMessage ("Authentication Failed", Const.CRITICAL, "Authentication check");
ecode=Const.AUTHENTICATION_FAILED;
}
}catch(IOException e1){
//DO nothing???
}
catch (NoSuchAlgorithmException e2) {
da.appendDebug("Algorithm not supported");
da.displayMessage ("Encryption Algorithm NOT supported", Const.EXCLAMATION, "Authentication check");
}
catch (InvalidKeyException e3) {
da.appendDebug("Invalid public key");
da.displayMessage ("Invalid public key", Const.EXCLAMATION, "Authentication check");
}
catch (SignatureException e4) {
da.appendDebug("Invalid signature");
da.displayMessage ("Invalid signature", Const.EXCLAMATION, "Authentication check");
}
}
else if(func_id==Const.SrvRqstAuth)
{
try{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(bos);
dos.writeShort(_spi.length);
dos.write(_spi);
dos.writeShort(type.getBytes().length);
dos.write(type.getBytes());
dos.writeShort(scope.getBytes().length);
dos.write(scope.getBytes());
dos.writeShort(pred.getBytes().length);
dos.write(pred.getBytes());
dos.writeInt(timeStamp);
byte[] data=bos.toByteArray();
Signature signature = Signature.getInstance("SHA1withRSA");
signature.initVerify(_publicKey);
signature.update(data);
boolean verify=signature.verify(_sign);
if(verify){
da.append("> Athentication Executed Correctly");
}
else{
da.append("> Error: Authentication Failed");
ecode=Const.AUTHENTICATION_FAILED;
}
}catch(IOException e1){
//DO nothing???
}
catch (NoSuchAlgorithmException e2) {
da.appendDebug("Encryption Algorithm not supported");
da.displayMessage ("Encryption Algorithm NOT supported", Const.EXCLAMATION, "Authentication check");
}
catch (InvalidKeyException e3) {
da.appendDebug("Invalid public key");
da.displayMessage ("Invalid public key", Const.EXCLAMATION, "Authentication check");
}
catch (SignatureException e4) {
da.appendDebug("Invalid signature");
da.displayMessage ("Invalid signature", Const.EXCLAMATION, "Authentication check");
}
}
}
}
/**
* service De-registration <#4>
*+-----------------------------+---------------------------+
*| Length of <scope-list> | <scope-list> \
*+-----------------------------+---------------------------+
*| <URL-entry> \
*+-----------------------------+---------------------------+
*| Length of <tag-list> | <tag-list> \
*+-----------------------------+---------------------------+
* Need to set error code, 0 is for OK
*/
public void SrvDeReg(byte[] buf, int[] ia) {
scope = Util.parseString(buf, ia); // scope list
parseURL(buf, ia); // URL
tag = Util.parseString(buf, ia); // tag list
if (Util.shareString(daf.getScope(), scope, ",")) {
ecode = database.rmEntry(ltag, url, scope, tag, versionTS,
acceptDA, acceptTS);
} else {
ecode = Const.SCOPE_NOT_SUPPORTED;
}
if (Const.MESSAGE_LOG_ENABLED && Const.SrvDeReg_LOG_ENABLED) da.append("\nINCOMING SRVDEREG MESSAGE" +
"\n- Xid = "+ xid +
"\n- Scope = " + scope +
"\n- Url = " + url +
"\n- Tag List = " + tag +
"\n");
}
/**
* service ack (reply for SrvReg & SrvDeReg) <#5>
*+-----------------------------+
*| Error Code |
*+-----------------------------+
* return the error code
*/
public void SrvAck(byte[] buf, int[] ia) {
ecode = Util.parseInt(buf, ia, 2);
if (Const.MESSAGE_LOG_ENABLED && Const.SrvAck_LOG_ENABLED) da.append("\nINCOMING SRVACK MESSAGE" +
"\n-Xid = "+ xid +
"\n- Error = " + ecode +
"\n");
}
/**
* attribute request <#6>
*+-------------------------------+----------------------------+
*| length of PRList | <PRList> string \
*+-------------------------------+----------------------------+
*| length of URL | URL \
*+-------------------------------+----------------------------+
*| length of <scope-list> | <scope-list> string \
*+-------------------------------+----------------------------+
*| length of <tag-list> string | <tag-list> string \
*+-------------------------------+----------------------------+
*| length of <SLP SPI> string | <SLP SPI> string \
*+-------------------------------+----------------------------+
*/
public void AttrRqst(byte[] buf, int[] ia) {
da.appendDebug("slpMsgParser::AttrRqst");
prlist = Util.parseString(buf, ia); // PRList
url = Util.parseString(buf, ia); // URL or Service type
scope = Util.parseString(buf, ia); // scope list
tag = Util.parseString(buf, ia); // tag list
spi = Util.parseString(buf, ia); // SLP SPI string
/*
* Check if at least one scope is in the list of the DA
*/
if (!Util.shareString(daf.getScope(), scope, ","))
{
// NO SCOPES...
ecode = Const.SCOPE_NOT_SUPPORTED;
attrList = "";
}
else
{
ecode = Const.OK;
attrList = database.getAttrList(url, scope, tag, ltag);
}
if (Const.MESSAGE_LOG_ENABLED && Const.AttrRqst_LOG_ENABLED) {
da.append("\nINCOMING ATTRRQST MESSAGE"+
"\n- Xid = "+ xid +
"\n- Scope = " + scope +
"\n- Attribute List = " + tag +
"\n- Service URL or Type = " + url +
"\n- Prlist = " + prlist +
"\n- Spi = " + spi +
"\n");
}
}
/**
* attribute reply (reply for attribute request) <#7>
*+-----------------------------+---------------------------------+
*| Error Code | length of <attr-list> |
*+-----------------------------+---------------------------------+
*| <attr-list> \
*+----------------+----------------------------------------------+
*| # of AttrAuths | Attribute authentication block (if present) \
*+----------------+----------------------------------------------+
*/
public void AttrReply(byte[] buf, int[] ia) {
ecode = Util.parseInt(buf, ia, 2);
attrList = Util.parseString(buf, ia);
if (Const.MESSAGE_LOG_ENABLED && Const.AttrRply_LOG_ENABLED){
da.append("\nINCOMING ATTRREPLY MESSAGE"+
"\n- Xid = "+ xid +
"\n- Error = " + ecode +
"\n- Attribute List = " + attrList +
"\n");
}
}
/**
* directory agent advertisement <#8>
*+-------------------------------+--------------------------------+
*| Error Code | DA Stateless Boot Timestamp |
*+-------------------------------+--------------------------------+
*| DA Stateless Boot Time cont. | length of URL |
*+-------------------------------+--------------------------------+
*| URL \
*+-------------------------------+--------------------------------+
*| length of <scope-list> | <scope-list> \
*+-------------------------------+--------------------------------+
*| length of <attr-list> | <attr-list> \
*+-------------------------------+--------------------------------+
*| length of SLP <SPI> | SLP <SPI> string \
*+---------------+---------------+--------------------------------+
*| # Auth Blocks | Authentication block (if any) \
*+---------------+---------------+--------------------------------+
*/
public void DAAdvert(byte[] buf, int[] ia) {
/*da.appendDebug("\n\n\n\nslpMsgPrs::DAADVERT\n\n\n\n");
for (int i=0; i<buf.length;i++){
da.appendDebug(buf[i]);
}*/
ecode = Util.parseInt(buf, ia, 2);
daBootTS = Util.parseInt(buf, ia, 4); // boot timestamp
url = Util.parseString(buf, ia); // URL
scope = Util.parseString(buf, ia); // scope-list
attr = Util.parseString(buf, ia); // attr-list
da.appendDebug("slpMsgParser::DAAdvert-URL ="+url);
if (Const.MESSAGE_LOG_ENABLED && Const.DAAdvert_LOG_ENABLED) da.append("\nINCOMING DAADVERT MESSAGE"+
"\n- Xid = "+ xid +
"\n- Url = " + url +
"\n- Scope = " + scope +
"\n- Attribute List = " + attr +
"\n");
}
/**
* service type request <#9>
*+-------------------------------+-----------------------------+
*| length of PRList | <PRList> string |
*+-------------------------------+-----------------------------+
*| length of Naming Authority | <Naming Authority String> |
*+-------------------------------+-----------------------------+
*| length of <scope-list> | <scope-list> string |
*+-------------------------------+-----------------------------+
*/
public void SrvTypeRqst(byte[] buf, int[] ia) {
prlist = Util.parseString(buf, ia); // PRList
String na = Util.parseString(buf, ia); // Naming authority
scope = Util.parseString(buf, ia); // scope list
if (!Util.shareString(daf.getScope(), scope, ","))
{
ecode = Const.SCOPE_NOT_SUPPORTED;
typeList = "";
}
else
{
ecode = Const.OK;
typeList = database.getServiceTypeList(na, scope);
}
if (Const.MESSAGE_LOG_ENABLED && Const.SrvTypeRqst_LOG_ENABLED)
{
da.append("\nINCOMING SRVTYPERQST MESSAGE"+
"\n- Xid = "+ xid +
"\n- PRList = " + prlist +
"\n- Naming Authority = " + na +
"\n- Scope = " + scope +
"\n");
}
}
/**
* service type reply (reply for service type request) <#10>
*+-------------------------------+-------------------------------+
*| Error Code | length of <srvType-list> |
*+-------------------------------+-------------------------------+
*| <srvType-list> |
*+---------------------------------------------------------------+
*/
public void SrvTypeReply(byte[] buf, int[] ia) {
ecode = Util.parseInt(buf, ia, 2);
typeList = Util.parseString(buf, ia);
if (Const.MESSAGE_LOG_ENABLED && Const.SrvTypeRply_LOG_ENABLED)
{
da.append("\nINCOMING SRVTYPEREPLY MESSAGE"+
"\n- Xid = "+ xid +
"\n- Type List = " + typeList +
"\n");
}
}
/**
* AntiEtrpRqst <#12> message
*+-------------------------------+-------------------------------+
*| Anti-entropy type ID | Number of Accept ID entries |
*+-------------------------------+-------------------------------+
*| Accept ID Entry 1 ... Accept ID Entry k \
*+---------------------------------------------------------------+
*/
public void AntiEtrpRqst(byte[] buf, int[] ia) {
etrpType = Util.parseInt(buf, ia, 2);
int k = Util.parseInt(buf, ia, 2);
atsList.clear();
adaList.clear();
for (int i=0; i<k; i++) {
atsList.addElement(new Long(Util.parseLong(buf, ia)));
adaList.addElement(Util.parseString(buf, ia));
}
if (Const.MESSAGE_LOG_ENABLED && Const.AntiEtrpRqst_LOG_ENABLED) da.append("\nINCOMING ANTIETRPRQST MESSAGE"+
"\n- Xid = "+ xid +
"\n- Entropy Type = " + etrpType +
"\n- ATS List = " + atsList.toString() +
"\n- ADA List = " + adaList.toString() +
"\n");
}
/**
* Mesh Forwarding extension parser:
* (1) initialize (turn off previous value)
* (2) if MeshFwdExt,
* get Fwd-ID & versionTS
* if Fwd-ID == Const.RqstFwd, change it to Const.Fwded
* if Fwd-ID == Const.Fwded, get acceptDA & acceptTS
*+--------------------------------+----------------------------------+
*| MeshFwd Extension ID = 0x0006 | Next Extension Offset (NEO) |
*+--------------+-----------------+----------------------------------+
*| NEO Contd. | Fwd-ID | Version Timestamp |
*+--------------+-----------------+----------------------------------+
*| Version Timestamp, contd. |
*+--------------------------------+----------------------------------+
*| Version Timestamp, contd. | Accept ID \
*+--------------------------------+----------------------------------+
*/
public void MeshFwdExt(byte[] buf, String fromPeer) { // buf: whole msg
meshFwdID = -1; // no MeshFwdExt
acceptDA = daf.getFQDN();
acceptTS = System.currentTimeMillis();
versionTS = acceptTS;
int[] ia = { ext_offset }; // initial extension offset
while (ia[0] != Const.EndOfExt) { // while has more extensions
int extID = Util.parseInt(buf, ia, 2); // extension ID
int nextExt = Util.parseInt(buf, ia, 3); // next extension
if (extID == Const.MeshFwdExt) { // mesh-forwarding extension
int idAddr = ia[0]; // may need to MeshFwdID
meshFwdID = Util.parseInt(buf, ia, 1);
versionTS = Util.parseLong(buf, ia);
if (meshFwdID == Const.Fwded) {
acceptTS = Util.parseLong(buf, ia);
acceptDA = Util.parseString(buf, ia);
daf.setSummary(acceptDA, acceptTS, fromPeer);
} else if (meshFwdID == Const.RqstFwd) {
Util.writeInt(buf, idAddr, Const.Fwded, 1);
Util.writeLong(buf, idAddr+9, acceptTS);
}
break; // at most one MeshFwd extension
}
ia[0] = nextExt;
}
if (meshFwdID != Const.Fwded) { // accepted by local host
daf.setSummary(acceptDA, acceptTS, acceptDA);
}
}
public void SelectSortExt(byte[] buf) { // buf: whole message
ssExtList.clear();
hasSelectExt = false;
int[] ia = { ext_offset }; // initial extension offset
while (ia[0] != Const.EndOfExt) { // while has more extensions
int extID = Util.parseInt(buf, ia, 2); // extension ID
int nextExt = Util.parseInt(buf, ia, 3); // next extension
if (extID == Const.SelectExt) { // selection extension
hasSelectExt = true;
int num = Util.parseInt(buf, ia, 2);
ssExtList.addElement(new SelectSortExt(Const.SelectExt, num));
} else if (extID == Const.SortExt) { // sort extension
String key = Util.parseString(buf, ia);
ssExtList.addElement(new SelectSortExt(Const.SortExt, key));
}
ia[0] = nextExt;
}
}
public void AttrListExt(byte[] buf) { // buf: whole message
urlVector.clear();
attrVector.clear();
hasAttrListExt = false;
int[] ia = { ext_offset }; // initial extension offset
while (ia[0] != Const.EndOfExt) { // while has more extensions
int extID = Util.parseInt(buf, ia, 2); // extension ID
int nextExt = Util.parseInt(buf, ia, 3); // next extension
if (extID == Const.AttrListExt) { // AttrList extension
hasAttrListExt = true;
urlVector.addElement(Util.parseString(buf, ia)); // url
attrVector.addElement(Util.parseString(buf, ia)); // attr
}
ia[0] = nextExt;
}
}
}
|