| Method from com.sun.jndi.ldap.Connection Detail: |
synchronized void abandonOutstandingReqs(Control[] reqCtls) {
LdapRequest ldr = pendingRequests;
while (ldr != null) {
abandonRequest(ldr, reqCtls);
pendingRequests = ldr = ldr.next;
}
}
|
void abandonRequest(LdapRequest ldr,
Control[] reqCtls) {
// Remove from queue
removeRequest(ldr);
BerEncoder ber = new BerEncoder(256);
int abandonMsgId = getMsgId();
//
// build the abandon request.
//
try {
ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
ber.encodeInt(abandonMsgId);
ber.encodeInt(ldr.msgId, LdapClient.LDAP_REQ_ABANDON);
if (v3) {
LdapClient.encodeControls(ber, reqCtls);
}
ber.endSeq();
if (traceFile != null) {
Ber.dumpBER(traceFile, traceTagOut, ber.getBuf(), 0,
ber.getDataLen());
}
synchronized (this) {
outStream.write(ber.getBuf(), 0, ber.getDataLen());
outStream.flush();
}
} catch (IOException ex) {
//System.err.println("ldap.abandon: " + ex);
}
// Dont expect any response for the abandon request.
}
|
void cleanup(Control[] reqCtls,
boolean notifyParent) {
boolean nparent = false;
synchronized (this) {
useable = false;
if (sock != null) {
if (debug) {
System.err.println("Connection: closing socket: " + host + "," + port);
}
try {
if (!notifyParent) {
abandonOutstandingReqs(reqCtls);
}
if (bound) {
ldapUnbind(reqCtls);
}
} finally {
try {
outStream.flush();
sock.close();
unpauseReader();
} catch (IOException ie) {
if (debug)
System.err.println("Connection: problem closing socket: " + ie);
}
if (!notifyParent) {
LdapRequest ldr = pendingRequests;
while (ldr != null) {
ldr.cancel();
ldr = ldr.next;
}
}
sock = null;
}
nparent = notifyParent;
}
}
if (nparent) {
parent.processConnectionClosure();
}
}
|
synchronized LdapRequest findRequest(int msgId) {
LdapRequest ldr = pendingRequests;
while (ldr != null) {
if (ldr.msgId == msgId) {
return ldr;
}
ldr = ldr.next;
}
return null;
}
|
synchronized int getMsgId() {
return ++outMsgId;
}
|
BerDecoder readReply(LdapRequest ldr) throws NamingException, IOException {
BerDecoder rber;
boolean waited = false;
while (((rber = ldr.getReplyBer()) == null) && !waited) {
try {
// If socket closed, don't even try
synchronized (this) {
if (sock == null) {
throw new ServiceUnavailableException(host + ":" + port +
"; socket closed");
}
}
synchronized (ldr) {
// check if condition has changed since our last check
rber = ldr.getReplyBer();
if (rber == null) {
if (readTimeout > 0) { // Socket read timeout is specified
// will be woken up before readTimeout only if reply is
// available
ldr.wait(readTimeout);
waited = true;
} else {
ldr.wait(15 * 1000); // 15 second timeout
}
} else {
break;
}
}
} catch (InterruptedException ex) {
throw new InterruptedNamingException(
"Interrupted during LDAP operation");
}
}
if ((rber == null) && waited) {
removeRequest(ldr);
throw new NamingException("LDAP response read timed out, timeout used:"
+ readTimeout + "ms." );
}
return rber;
}
Reads a reply; waits until one is ready. |
synchronized void removeRequest(LdapRequest req) {
LdapRequest ldr = pendingRequests;
LdapRequest ldrprev = null;
while (ldr != null) {
if (ldr == req) {
ldr.cancel();
if (ldrprev != null) {
ldrprev.next = ldr.next;
} else {
pendingRequests = ldr.next;
}
ldr.next = null;
}
ldrprev = ldr;
ldr = ldr.next;
}
}
|
public synchronized void replaceStreams(InputStream newIn,
OutputStream newOut) {
if (debug) {
System.err.println("Replacing " + inStream + " with: " + newIn);
System.err.println("Replacing " + outStream + " with: " + newOut);
}
inStream = newIn;
// Cleanup old stream
try {
outStream.flush();
} catch (IOException ie) {
if (debug)
System.err.println("Connection: cannot flush outstream: " + ie);
}
// Replace stream
outStream = newOut;
}
|
public void run() {
byte inbuf[]; // Buffer for reading incoming bytes
int inMsgId; // Message id of incoming response
int bytesread; // Number of bytes in inbuf
int bytesleft; // Number of bytes that need to read for completing resp
int br; // Temp; number of bytes read from stream
int offset; // Offset of where to store bytes in inbuf
int seqlen; // Length of ASN sequence
int seqlenlen; // Number of sequence length bytes
boolean eos; // End of stream
BerDecoder retBer; // Decoder for ASN.1 BER data from inbuf
InputStream in = null;
try {
while (true) {
try {
inbuf = new byte[2048];
offset = 0;
seqlen = 0;
seqlenlen = 0;
in = getInputStream();
// check that it is the beginning of a sequence
bytesread = in.read(inbuf, offset, 1);
if (bytesread < 0) {
if (in != getInputStream()) {
continue; // a new stream to try
} else {
break; // EOF
}
}
if (inbuf[offset++] != (Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR))
continue;
// get length of sequence
bytesread = in.read(inbuf, offset, 1);
if (bytesread < 0)
break; // EOF
seqlen = inbuf[offset++];
// if high bit is on, length is encoded in the
// subsequent length bytes and the number of length bytes
// is equal to & 0x80 (i.e. length byte with high bit off).
if ((seqlen & 0x80) == 0x80) {
seqlenlen = seqlen & 0x7f; // number of length bytes
bytesread = 0;
eos = false;
// Read all length bytes
while (bytesread < seqlenlen) {
br = in.read(inbuf, offset+bytesread,
seqlenlen-bytesread);
if (br < 0) {
eos = true;
break; // EOF
}
bytesread += br;
}
// end-of-stream reached before length bytes are read
if (eos)
break; // EOF
// Add contents of length bytes to determine length
seqlen = 0;
for( int i = 0; i < seqlenlen; i++) {
seqlen = (seqlen < < 8) + (inbuf[offset+i] & 0xff);
}
offset += bytesread;
}
// read in seqlen bytes
bytesleft = seqlen;
if ((offset + bytesleft) > inbuf.length) {
byte nbuf[] = new byte[offset + bytesleft];
System.arraycopy(inbuf, 0, nbuf, 0, offset);
inbuf = nbuf;
}
while (bytesleft > 0) {
bytesread = in.read(inbuf, offset, bytesleft);
if (bytesread < 0)
break; // EOF
offset += bytesread;
bytesleft -= bytesread;
}
/*
if (dump > 0) {
System.err.println("seqlen: " + seqlen);
System.err.println("bufsize: " + offset);
System.err.println("bytesleft: " + bytesleft);
System.err.println("bytesread: " + bytesread);
}
*/
try {
retBer = new BerDecoder(inbuf, 0, offset);
if (traceFile != null) {
Ber.dumpBER(traceFile, traceTagIn, inbuf, 0, offset);
}
retBer.parseSeq(null);
inMsgId = retBer.parseInt();
retBer.reset(); // reset offset
boolean needPause = false;
if (inMsgId == 0) {
// Unsolicited Notification
parent.processUnsolicited(retBer);
} else {
LdapRequest ldr = findRequest(inMsgId);
if (ldr != null) {
/**
* Grab pauseLock before making reply available
* to ensure that reader goes into paused state
* before writer can attempt to unpause reader
*/
synchronized (pauseLock) {
needPause = ldr.addReplyBer(retBer);
if (needPause) {
/*
* Go into paused state; release
* pauseLock
*/
pauseReader();
}
// else release pauseLock
}
} else {
// System.err.println("Cannot find" +
// "LdapRequest for " + inMsgId);
}
}
} catch (Ber.DecodeException e) {
//System.err.println("Cannot parse Ber");
}
} catch (IOException ie) {
if (debug) {
System.err.println("Connection: Inside Caught " + ie);
ie.printStackTrace();
}
if (in != getInputStream()) {
// A new stream to try
// Go to top of loop and continue
} else {
if (debug) {
System.err.println("Connection: rethrowing " + ie);
}
throw ie; // rethrow exception
}
}
}
if (debug) {
System.err.println("Connection: end-of-stream detected: "
+ in);
}
} catch (IOException ex) {
if (debug) {
System.err.println("Connection: Caught " + ex);
}
closureReason = ex;
} finally {
cleanup(null, true); // cleanup
}
if (debug) {
System.err.println("Connection: Thread Exiting");
}
}
|
void setBound() {
bound = true;
}
|
void setV3(boolean v) {
// true means v3; false means v2
// Called in LdapClient.authenticate() (which is synchronized)
// when connection is "quiet" and not shared; no need to synchronize
v3 = v;
}
|
LdapRequest writeRequest(BerEncoder ber,
int msgId) throws IOException {
return writeRequest(ber, msgId, false /* pauseAfterReceipt */);
}
|
LdapRequest writeRequest(BerEncoder ber,
int msgId,
boolean pauseAfterReceipt) throws IOException {
LdapRequest req = new LdapRequest(msgId, pauseAfterReceipt);
addRequest(req);
if (traceFile != null) {
Ber.dumpBER(traceFile, traceTagOut, ber.getBuf(), 0, ber.getDataLen());
}
// unpause reader so that it can get response
// NOTE: Must do this before writing request, otherwise might
// create a race condition where the writer unblocks its own response
unpauseReader();
if (debug) {
System.err.println("Writing request to: " + outStream);
}
try {
synchronized (this) {
outStream.write(ber.getBuf(), 0, ber.getDataLen());
outStream.flush();
}
} catch (IOException e) {
cleanup(null, true);
throw (closureReason = e); // rethrow
}
return req;
}
|