package com.sun.slp;
import java.util.*;
import java.net.*;
abstract class ServerDATable extends DATable {
protected static ActiveDiscoverer activeDiscoverer = null;
protected Hashtable forwardRegs = new Hashtable();
private static Object readyLock = new Object();
protected Hashtable daSPIsHash = new Hashtable();
static ServerDATable getServerDATable()
throws ServiceLocationException {
ServerDATable table = null;
synchronized (readyLock) {
if (daTable != null) {
return (ServerDATable)daTable;
}
conf = SLPConfig.getSLPConfig();
daTable = linkAndInstantiateFromProp();
table = (ServerDATable)daTable;
Vector useScopes = new Vector();
activeDiscoverer =
new ActiveDiscoverer(Defaults.version,
table,
useScopes,
conf.getMulticastAddress());
activeDiscoverer.start();
}
return table;
}
abstract long
recordNewDA(ServiceURL url,
Vector scopes,
long timestamp,
int version,
Vector attrs,
String spis);
abstract Hashtable returnMatchingDAs(String query)
throws ServiceLocationException;
void forwardSAMessage(SrvLocMsg msg, InetAddress source)
throws ServiceLocationException {
SrvLocHeader hdr = msg.getHeader();
if (!conf.isLocalHostSource(source)) {
return;
}
if (msg instanceof SSrvReg || msg instanceof CSrvReg) {
ServiceURL url;
if (msg instanceof SSrvReg) {
url = ((SSrvReg)msg).URL;
} else {
url = ((CSrvReg)msg).URL;
}
String key = makeKey(url, hdr.locale);
forwardRegs.put(key, msg);
} else {
SSrvDereg smsg = (SSrvDereg)msg;
if (smsg.tags == null) {
String key = makeKey(smsg.URL, hdr.locale);
forwardRegs.remove(key);
}
}
Hashtable daScopeRec = findDAScopes(hdr.scopes);
Vector daRecs = (Vector)daScopeRec.get(UNICAST_KEY);
if (daRecs == null) {
return;
}
int i, n = daRecs.size();
for (i = 0; i < n; i++) {
DARecord rec = (DARecord)daRecs.elementAt(i);
Vector daAddresses = rec.daAddresses;
int j, m = daAddresses.size();
for (j = 0; j < m; j++) {
InetAddress addr = (InetAddress)daAddresses.elementAt(j);
if (!source.equals(addr)) {
forwardRegOrDereg(addr, msg);
}
}
}
}
private String makeKey(ServiceURL url, Locale locale) {
return url.toString() + "/" + locale.toString();
}
void handleAdvertIn(CDAAdvert advert) {
SrvLocHeader hdr = advert.getHeader();
if (advert.isGoingDown()) {
InetAddress addr = null;
try {
addr = InetAddress.getByName(advert.URL.getHost());
} catch (UnknownHostException ex) {
conf.writeLog("unknown_da_address",
new Object[] {advert.URL.getHost()});
return;
}
if (removeDA(addr, hdr.scopes)) {
if (conf.traceDATraffic()) {
conf.writeLog("sdat_delete_da",
new Object[] {
advert.URL,
hdr.scopes});
}
}
} else {
if (advert.authBlock != null) {
try {
AuthBlock.verifyAll(advert.authBlock);
} catch (ServiceLocationException e) {
if (conf.traceDrop()) {
conf.writeLog("sdat_daadvert_vrfy_failed",
new Object[] {advert.URL});
}
return;
}
}
long timestamp =
recordNewDA(advert.URL,
hdr.scopes,
advert.timestamp,
hdr.version,
advert.attrs,
advert.spis);
if (timestamp >= advert.timestamp) {
if (conf.traceDATraffic()) {
conf.writeLog("sdat_add_da_no_forward",
new Object[] {
advert.URL,
hdr.scopes,
Long.valueOf(timestamp)});
}
return;
}
if (conf.traceDATraffic()) {
conf.writeLog("sdat_add_da",
new Object[] {
advert.URL,
hdr.scopes,
Long.valueOf(advert.timestamp)});
}
forwardRegistrations(advert.URL, hdr.scopes,
advert.timestamp, hdr.version);
}
}
private void
forwardRegistrations(ServiceURL url,
Vector scopes,
long timestamp,
int version) {
try {
Thread.currentThread().sleep(conf.getRandomWait());
} catch (InterruptedException ex) {
}
Enumeration regs = forwardRegs.elements();
InetAddress addr = null;
String host = url.getHost();
try {
addr = InetAddress.getByName(host);
} catch (UnknownHostException ex) {
if (conf.traceDrop() || conf.traceDATraffic()) {
conf.writeLog("sdat_drop_fwd",
new Object[] {
host});
}
return;
}
ServiceTable serviceTable = null;
try {
serviceTable = ServiceTable.getServiceTable();
} catch (ServiceLocationException ex) {
}
Vector deleted = new Vector();
while (regs.hasMoreElements()) {
SrvLocMsg reg = (SrvLocMsg)regs.nextElement();
ServiceURL regurl;
if (reg instanceof SSrvReg) {
regurl = ((SSrvReg)reg).URL;
} else {
regurl = ((CSrvReg)reg).URL;
}
SrvLocHeader hdr = reg.getHeader();
ServiceStore.ServiceRecord rec =
serviceTable.getServiceRecord(regurl, hdr.locale);
if (rec == null) {
deleted.addElement(reg);
} else {
Vector sscopes = (Vector)hdr.scopes.clone();
DATable.filterScopes(sscopes, scopes, false);
if (sscopes.size() <= 0) {
continue;
}
if (reg instanceof SSrvReg) {
SSrvReg sreg = (SSrvReg)reg;
hdr.scopes = (Vector)hdr.scopes.clone();
sreg.attrList = (Vector)rec.getAttrList().clone();
sreg.URLSignature = rec.getURLSignature();
sreg.attrSignature = rec.getAttrSignature();
}
forwardRegOrDereg(addr, reg);
}
}
int i, n = deleted.size();
for (i = 0; i < n; i++) {
SrvLocMsg reg = (SrvLocMsg)deleted.elementAt(i);
SrvLocHeader hdr = reg.getHeader();
ServiceURL regurl;
if (reg instanceof SSrvReg) {
regurl = ((SSrvReg)reg).URL;
} else {
regurl = ((CSrvReg)reg).URL;
}
String key = makeKey(regurl, hdr.locale);
forwardRegs.remove(key);
}
}
private void forwardRegOrDereg(InetAddress addr, SrvLocMsg rqst) {
SrvLocHeader hdr = rqst.getHeader();
if (conf.isLocalHostSource(addr)) {
return;
}
if (conf.getHasSecurity()) {
LinkedList spis = (LinkedList)daSPIsHash.get(addr);
if (spis == null) {
return;
}
Hashtable auths = null;
if (rqst instanceof SSrvReg) {
auths = ((SSrvReg)rqst).URLSignature;
} else if (rqst instanceof SSrvDereg) {
auths = ((SSrvDereg)rqst).URLSignature;
} else {
return;
}
Enumeration abs = auths.elements();
while (abs.hasMoreElements()) {
AuthBlock ab = (AuthBlock)abs.nextElement();
boolean daSPImatch = false;
for (int SPIi = 0; SPIi < spis.size(); SPIi++) {
if (AuthBlock.checkEquiv((String)spis.get(SPIi), ab)) {
daSPImatch = true;
break;
}
}
if (!daSPImatch) {
return;
}
}
}
if (conf.traceDATraffic()) {
conf.writeLog("sdat_forward",
new Object[] {
Integer.toHexString(hdr.xid),
addr});
}
SrvLocMsg rply = null;
try {
if (rqst instanceof SSrvReg) {
SSrvReg rrqst = (SSrvReg)rqst;
CSrvReg msg = new CSrvReg(hdr.fresh,
hdr.locale,
rrqst.URL,
hdr.scopes,
rrqst.attrList,
rrqst.URLSignature,
rrqst.attrSignature);
rply = msg;
} else if (rqst instanceof SSrvDereg) {
SSrvDereg drqst = (SSrvDereg)rqst;
CSrvDereg msg = new CSrvDereg(hdr.locale,
drqst.URL,
hdr.scopes,
drqst.tags,
drqst.URLSignature);
rply = msg;
} else if (rqst instanceof CSrvReg) {
rply = rqst;
}
rply = Transact.transactTCPMsg(addr, rply, false);
} catch (ServiceLocationException ex) {
if (conf.traceDATraffic()) {
conf.writeLog("sdat_forward_exception",
new Object[] {
Integer.toHexString(hdr.xid),
addr,
Integer.valueOf(ex.getErrorCode()),
ex.getMessage()});
}
}
if (rply == null ||
rply.getErrorCode() != ServiceLocationException.OK) {
if (conf.traceDATraffic()) {
conf.writeLog("sdat_forward_err",
new Object[] {
Integer.toHexString(hdr.xid),
addr,
(rply == null ? "<null>":
Integer.toString(rply.getErrorCode()))});
}
}
}
}