aboutsummaryrefslogtreecommitdiffstats
path: root/java/com/tigervnc
diff options
context:
space:
mode:
authorBrian Hinz <bphinz@users.sourceforge.net>2012-03-18 21:39:04 +0000
committerBrian Hinz <bphinz@users.sourceforge.net>2012-03-18 21:39:04 +0000
commit35022e07a90807f5f0686c146e49f469d4b3f2fd (patch)
tree9734715a7e8f83eb7c6d31867e5cef7e7be0f5e8 /java/com/tigervnc
parentef41e92001036029284c7bcfb6a9249cc2008a87 (diff)
downloadtigervnc-35022e07a90807f5f0686c146e49f469d4b3f2fd.tar.gz
tigervnc-35022e07a90807f5f0686c146e49f469d4b3f2fd.zip
Changes aimed at making the behavior of the java client more consistent with the binary client.
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@4871 3789f03b-4d11-0410-bbf8-ca57d06f2519
Diffstat (limited to 'java/com/tigervnc')
-rw-r--r--java/com/tigervnc/network/FileDescriptor.java2
-rw-r--r--java/com/tigervnc/network/SocketDescriptor.java31
-rw-r--r--java/com/tigervnc/rdr/FdInStream.java73
-rw-r--r--java/com/tigervnc/rdr/FdOutStream.java20
-rw-r--r--java/com/tigervnc/rdr/InStream.java21
-rw-r--r--java/com/tigervnc/rfb/CConnection.java138
-rw-r--r--java/com/tigervnc/rfb/ConnParams.java1
-rw-r--r--java/com/tigervnc/vncviewer/CConn.java3
8 files changed, 177 insertions, 112 deletions
diff --git a/java/com/tigervnc/network/FileDescriptor.java b/java/com/tigervnc/network/FileDescriptor.java
index 28ea96b8..12f6d586 100644
--- a/java/com/tigervnc/network/FileDescriptor.java
+++ b/java/com/tigervnc/network/FileDescriptor.java
@@ -25,7 +25,7 @@ public interface FileDescriptor {
public int read(byte[] buf, int bufPtr, int length) throws Exception;
public int write(byte[] buf, int bufPtr, int length) throws Exception;
- public int select(int interestOps, int timeout) throws Exception;
+ public int select(int interestOps, Integer timeout) throws Exception;
public void close() throws IOException;
}
diff --git a/java/com/tigervnc/network/SocketDescriptor.java b/java/com/tigervnc/network/SocketDescriptor.java
index 95ee84ae..f9207316 100644
--- a/java/com/tigervnc/network/SocketDescriptor.java
+++ b/java/com/tigervnc/network/SocketDescriptor.java
@@ -88,32 +88,37 @@ public class SocketDescriptor extends SocketChannel
return n;
}
- synchronized public int select(int interestOps, int timeout) throws Exception {
+ synchronized public int select(int interestOps, Integer timeout) throws Exception {
int n;
+ selector.selectedKeys().clear();
try {
- if (timeout == 0) {
- n = selector.selectNow();
+ if (timeout == null) {
+ n = selector.select();
} else {
- n = selector.select(timeout);
+ int tv = timeout.intValue();
+ switch(tv) {
+ case 0:
+ n = selector.selectNow();
+ break;
+ default:
+ n = selector.select((long)tv);
+ break;
+ }
}
+ if (n == 0)
+ return -1;
} catch (java.io.IOException e) {
throw new Exception(e.toString());
}
- if (n == 0)
- return -1;
Set keys = selector.selectedKeys();
Iterator iter = keys.iterator();
while (iter.hasNext()) {
SelectionKey key = (SelectionKey)iter.next();
- if ((key.readyOps() & interestOps) != 0) {
- n = 1;
- break;
- } else {
- n = -1;
+ if ((key.readyOps() & interestOps) != 0) {
+ return n;
}
}
- keys.clear();
- return n;
+ return 0;
}
public int write(ByteBuffer buf) throws Exception {
diff --git a/java/com/tigervnc/rdr/FdInStream.java b/java/com/tigervnc/rdr/FdInStream.java
index ea81388f..faf98693 100644
--- a/java/com/tigervnc/rdr/FdInStream.java
+++ b/java/com/tigervnc/rdr/FdInStream.java
@@ -27,21 +27,36 @@ import java.util.Iterator;
public class FdInStream extends InStream {
- static final int defaultBufSize = 8192;
+ static final int DEFAULT_BUF_SIZE = 8192;
static final int minBulkSize = 1024;
- public FdInStream(FileDescriptor fd_, int bufSize_) {
- fd = fd_;
- bufSize = bufSize_;
+ public FdInStream(FileDescriptor fd_, int timeoutms_, int bufSize_,
+ boolean closeWhenDone_)
+ {
+ fd = fd_; closeWhenDone = closeWhenDone_;
+ timeoutms = timeoutms_; blockCallback = null;
+ timing = false; timeWaitedIn100us = 5; timedKbits = 0;
+ bufSize = ((bufSize_ > 0) ? bufSize_ : DEFAULT_BUF_SIZE);
+ b = new byte[bufSize];
+ ptr = end = offset = 0;
+ }
+
+ public FdInStream(FileDescriptor fd_) { this(fd_, -1, 0, false); }
+
+ public FdInStream(FileDescriptor fd_, FdInStreamBlockCallback blockCallback_,
+ int bufSize_)
+ {
+ fd = fd_; timeoutms = 0; blockCallback = blockCallback_;
+ timing = false; timeWaitedIn100us = 5; timedKbits = 0;
+ bufSize = ((bufSize_ > 0) ? bufSize_ : DEFAULT_BUF_SIZE);
b = new byte[bufSize];
ptr = end = offset = 0;
- timeoutms = 0;
- timing = false;
- timeWaitedIn100us = 5;
- timedKbits = 0;
}
- public FdInStream(FileDescriptor fd_) { this(fd_, defaultBufSize); }
+ public FdInStream(FileDescriptor fd_,
+ FdInStreamBlockCallback blockCallback_) {
+ this(fd_, blockCallback_, 0);
+ }
public final void readBytes(byte[] data, int dataPtr, int length) {
if (length < minBulkSize) {
@@ -100,7 +115,8 @@ public class FdInStream extends InStream {
public final long timeWaited() { return timeWaitedIn100us; }
- protected int overrun(int itemSize, int nItems, boolean wait) {
+ protected int overrun(int itemSize, int nItems, boolean wait)
+ {
if (itemSize > bufSize)
throw new Exception("FdInStream overrun: max itemSize exceeded");
@@ -136,26 +152,28 @@ public class FdInStream extends InStream {
protected int readWithTimeoutOrCallback(byte[] buf, int bufPtr, int len, boolean wait) {
long before = 0;
- int timeout;
if (timing)
before = System.nanoTime();
int n;
while (true) {
+ do {
+ Integer tv;
- if (!wait) {
- timeout = 0;
- } else if (timeoutms != -1) {
- timeout = timeoutms;
- } else {
- timeout = 0;
- }
-
- try {
- n = fd.select(SelectionKey.OP_READ, timeout);
- } catch (Exception e) {
- throw new SystemException("select:"+e.toString());
- }
+ if (!wait) {
+ tv = new Integer(0);
+ } else if (timeoutms != -1) {
+ tv = new Integer(timeoutms);
+ } else {
+ tv = null;
+ }
+
+ try {
+ n = fd.select(SelectionKey.OP_READ, tv);
+ } catch (Exception e) {
+ throw new SystemException("select:"+e.toString());
+ }
+ } while (n < 0);
if (n > 0) break;
@@ -205,11 +223,12 @@ public class FdInStream extends InStream {
fd = fd_;
}
- private int offset;
- private int bufSize;
private FileDescriptor fd;
- private FdInStreamBlockCallback blockCallback;
+ boolean closeWhenDone;
protected int timeoutms;
+ private FdInStreamBlockCallback blockCallback;
+ private int offset;
+ private int bufSize;
protected boolean timing;
protected long timeWaitedIn100us;
diff --git a/java/com/tigervnc/rdr/FdOutStream.java b/java/com/tigervnc/rdr/FdOutStream.java
index c7767245..ce89f1ec 100644
--- a/java/com/tigervnc/rdr/FdOutStream.java
+++ b/java/com/tigervnc/rdr/FdOutStream.java
@@ -24,22 +24,20 @@ import java.nio.channels.SelectionKey;
public class FdOutStream extends OutStream {
- static final int defaultBufSize = 16384;
+ static final int DEFAULT_BUF_SIZE = 16384;
static final int minBulkSize = 1024;
public FdOutStream(FileDescriptor fd_, boolean blocking_, int timeoutms_, int bufSize_)
{
- fd = fd_;
- blocking = blocking_;
- timeoutms = timeoutms_;
- bufSize = bufSize_;
+ fd = fd_; blocking = blocking_; timeoutms = timeoutms_;
+ bufSize = ((bufSize_ > 0) ? bufSize_ : DEFAULT_BUF_SIZE);
b = new byte[bufSize];
offset = 0;
ptr = sentUpTo = start = 0;
end = start + bufSize;
}
- public FdOutStream(FileDescriptor fd_) { this(fd_, false, 0, defaultBufSize); }
+ public FdOutStream(FileDescriptor fd_) { this(fd_, true, -1, 0); }
public void setTimeout(int timeoutms_) {
timeoutms = timeoutms_;
@@ -93,19 +91,19 @@ public class FdOutStream extends OutStream {
private int writeWithTimeout(byte[] data, int dataPtr, int length, int timeoutms)
{
- int timeout;
int n;
do {
+ Integer tv;
if (timeoutms != -1) {
- timeout = timeoutms;
+ tv = new Integer(timeoutms);
} else {
- timeout = 0;
+ tv = null;
}
try {
- n = fd.select(SelectionKey.OP_WRITE, timeout);
+ n = fd.select(SelectionKey.OP_WRITE, tv);
} catch (java.lang.Exception e) {
System.out.println(e.toString());
throw new Exception(e.toString());
@@ -113,6 +111,8 @@ public class FdOutStream extends OutStream {
} while (n < 0);
+ if (n == 0) return 0;
+
try {
n = fd.write(data, dataPtr, length);
} catch (java.lang.Exception e) {
diff --git a/java/com/tigervnc/rdr/InStream.java b/java/com/tigervnc/rdr/InStream.java
index 8e58fbda..39de6f41 100644
--- a/java/com/tigervnc/rdr/InStream.java
+++ b/java/com/tigervnc/rdr/InStream.java
@@ -32,12 +32,11 @@ abstract public class InStream {
// maximum of nItems).
public int check(int itemSize, int nItems, boolean wait) {
- int available = end - ptr;
- if (itemSize * nItems > available) {
- if (itemSize > available)
+ if (ptr + itemSize * nItems > end) {
+ if (ptr + itemSize > end)
return overrun(itemSize, nItems, wait);
- nItems = available / itemSize;
+ nItems = (end - ptr) / itemSize;
}
return nItems;
}
@@ -53,10 +52,10 @@ abstract public class InStream {
// readU/SN() methods read unsigned and signed N-bit integers.
- public final int readS8() { check(1,1,true); return b[ptr++]; }
- public final int readS16() { check(2,1,true); int b0 = b[ptr++];
+ public final int readS8() { check(1); return b[ptr++]; }
+ public final int readS16() { check(2); int b0 = b[ptr++];
int b1 = b[ptr++] & 0xff; return b0 << 8 | b1; }
- public final int readS32() { check(4,1,true); int b0 = b[ptr++];
+ public final int readS32() { check(4); int b0 = b[ptr++];
int b1 = b[ptr++] & 0xff;
int b2 = b[ptr++] & 0xff;
int b3 = b[ptr++] & 0xff;
@@ -91,7 +90,7 @@ abstract public class InStream {
public final void skip(int bytes) {
while (bytes > 0) {
- int n = check(1, bytes, true);
+ int n = check(1, bytes);
ptr += n;
bytes -= n;
}
@@ -102,7 +101,7 @@ abstract public class InStream {
public void readBytes(byte[] data, int dataPtr, int length) {
int dataEnd = dataPtr + length;
while (dataPtr < dataEnd) {
- int n = check(1, dataEnd - dataPtr, true);
+ int n = check(1, dataEnd - dataPtr);
System.arraycopy(b, ptr, data, dataPtr, n);
ptr += n;
dataPtr += n;
@@ -115,10 +114,10 @@ abstract public class InStream {
public final int readOpaque8() { return readU8(); }
public final int readOpaque16() { return readU16(); }
public final int readOpaque32() { return readU32(); }
- public final int readOpaque24A() { check(3, 1, true); int b0 = b[ptr++];
+ public final int readOpaque24A() { check(3); int b0 = b[ptr++];
int b1 = b[ptr++]; int b2 = b[ptr++];
return b0 << 24 | b1 << 16 | b2 << 8; }
- public final int readOpaque24B() { check(3, 1, true); int b0 = b[ptr++];
+ public final int readOpaque24B() { check(3); int b0 = b[ptr++];
int b1 = b[ptr++]; int b2 = b[ptr++];
return b0 << 16 | b1 << 8 | b2; }
diff --git a/java/com/tigervnc/rfb/CConnection.java b/java/com/tigervnc/rfb/CConnection.java
index 0ec44044..1e55f043 100644
--- a/java/com/tigervnc/rfb/CConnection.java
+++ b/java/com/tigervnc/rfb/CConnection.java
@@ -25,31 +25,37 @@ import com.tigervnc.rdr.*;
abstract public class CConnection extends CMsgHandler {
- public CConnection() {
+ public CConnection()
+ {
+ csecurity = null; is = null; os = null; reader_ = null;
+ writer_ = null; shared = false;
+ state_ = RFBSTATE_UNINITIALISED; useProtocol3_3 = false;
security = new SecurityClient();
}
- // setStreams() sets the streams to be used for the connection. These must
- // be set before initialiseProtocol() and processMsg() are called. The
- // CSecurity object may call setStreams() again to provide alternative
- // streams over which the RFB protocol is sent (i.e. encrypting/decrypting
- // streams). Ownership of the streams remains with the caller
- // (i.e. SConnection will not delete them).
- public void setStreams(InStream is_, OutStream os_) {
- is = is_;
- os = os_;
+ // deleteReaderAndWriter() deletes the reader and writer associated with
+ // this connection. This may be useful if you want to delete the streams
+ // before deleting the SConnection to make sure that no attempt by the
+ // SConnection is made to read or write.
+ // XXX Do we really need this at all???
+ public void deleteReaderAndWriter()
+ {
+ reader_ = null;
+ writer_ = null;
}
// initialiseProtocol() should be called once the streams and security
// types are set. Subsequently, processMsg() should be called whenever
// there is data to read on the InStream.
- public void initialiseProtocol() {
+ public final void initialiseProtocol()
+ {
state_ = RFBSTATE_PROTOCOL_VERSION;
}
// processMsg() should be called whenever there is data to read on the
// InStream. You must have called initialiseProtocol() first.
- public void processMsg() {
+ public void processMsg()
+ {
switch (state_) {
case RFBSTATE_PROTOCOL_VERSION: processVersionMsg(); break;
@@ -65,7 +71,8 @@ abstract public class CConnection extends CMsgHandler {
}
}
- private void processVersionMsg() {
+ private void processVersionMsg()
+ {
vlog.debug("reading protocol version");
Boolean done = new Boolean(true);
if (!cp.readVersion(is, done)) {
@@ -74,8 +81,8 @@ abstract public class CConnection extends CMsgHandler {
}
if (!done.booleanValue()) return;
- vlog.info("Server supports RFB protocol version "+cp.majorVersion+"."+
- cp.minorVersion);
+ vlog.info("Server supports RFB protocol version "
+ +cp.majorVersion+"."+ cp.minorVersion);
// The only official RFB protocol versions are currently 3.3, 3.7 and 3.8
if (cp.beforeVersion(3,3)) {
@@ -97,15 +104,14 @@ abstract public class CConnection extends CMsgHandler {
cp.majorVersion+"."+cp.minorVersion);
}
- private void processSecurityTypesMsg() {
- vlog.info("processing security types message");
+ private void processSecurityTypesMsg()
+ {
+ vlog.debug("processing security types message");
int secType = Security.secTypeInvalid;
List<Integer> secTypes = new ArrayList<Integer>();
secTypes = Security.GetEnabledSecTypes();
- //for (Iterator i = secTypes.iterator(); i.hasNext(); )
- // vlog.info(((Integer)i.next()).toString());
if (cp.isVersion(3,3)) {
@@ -123,10 +129,10 @@ abstract public class CConnection extends CMsgHandler {
secType = refType;
break;
}
- if (!i.hasNext())
- secType = Security.secTypeInvalid;
}
+ if (!secTypes.contains(secType))
+ secType = Security.secTypeInvalid;
} else {
vlog.error("Unknown 3.3 security type "+secType);
throw new Exception("Unknown 3.3 security type");
@@ -140,9 +146,11 @@ abstract public class CConnection extends CMsgHandler {
if (nServerSecTypes == 0)
throwConnFailedException();
+ Iterator j;
+
for (int i = 0; i < nServerSecTypes; i++) {
int serverSecType = is.readU8();
- vlog.info("Server offers security type "+
+ vlog.debug("Server offers security type "+
Security.secTypeName(serverSecType)+"("+serverSecType+")");
/*
@@ -150,7 +158,7 @@ abstract public class CConnection extends CMsgHandler {
* It means server's order specifies priority.
*/
if (secType == Security.secTypeInvalid) {
- for (Iterator j = secTypes.iterator(); j.hasNext(); ) {
+ for (j = secTypes.iterator(); j.hasNext(); ) {
int refType = (Integer)j.next();
if (refType == serverSecType) {
secType = refType;
@@ -164,7 +172,7 @@ abstract public class CConnection extends CMsgHandler {
if (secType != Security.secTypeInvalid) {
os.writeU8(secType);
os.flush();
- vlog.info("Choosing security type "+Security.secTypeName(secType)+
+ vlog.debug("Choosing security type "+Security.secTypeName(secType)+
"("+secType+")");
}
}
@@ -246,10 +254,30 @@ abstract public class CConnection extends CMsgHandler {
// which we are connected. This might be the result of getPeerEndpoint on
// a TcpSocket, for example, or a host specified by DNS name & port.
// The serverName is used when verifying the Identity of a host (see RA2).
- public void setServerName(String name) {
+ public final void setServerName(String name) {
serverName = name;
}
+ // setStreams() sets the streams to be used for the connection. These must
+ // be set before initialiseProtocol() and processMsg() are called. The
+ // CSecurity object may call setStreams() again to provide alternative
+ // streams over which the RFB protocol is sent (i.e. encrypting/decrypting
+ // streams). Ownership of the streams remains with the caller
+ // (i.e. SConnection will not delete them).
+ public final void setStreams(InStream is_, OutStream os_)
+ {
+ is = is_;
+ os = os_;
+ }
+
+ // setShared sets the value of the shared flag which will be sent to the
+ // server upon initialisation.
+ public final void setShared(boolean s) { shared = s; }
+
+ // setProtocol3_3 configures whether or not the CConnection should
+ // only ever support protocol version 3.3
+ public final void setProtocol3_3(boolean s) { useProtocol3_3 = s; }
+
public void setServerPort(int port) {
serverPort = port;
}
@@ -258,15 +286,22 @@ abstract public class CConnection extends CMsgHandler {
nSecTypes = 0;
}
- // setShared sets the value of the shared flag which will be sent to the
- // server upon initialisation.
- public void setShared(boolean s) { shared = s; }
+ // Methods to be overridden in a derived class
- // setProtocol3_3 configures whether or not the CConnection should
- // only ever support protocol version 3.3
- public void setProtocol3_3(boolean s) { useProtocol3_3 = s; }
+ // getIdVerifier() returns the identity verifier associated with the connection.
+ // Ownership of the IdentityVerifier is retained by the CConnection instance.
+ //public IdentityVerifier getIdentityVerifier() { return 0; }
- // Methods to be overridden in a derived class
+ // authSuccess() is called when authentication has succeeded.
+ public void authSuccess() {}
+
+ // serverInit() is called when the ServerInit message is received. The
+ // derived class must call on to CConnection::serverInit().
+ public void serverInit()
+ {
+ state_ = RFBSTATE_NORMAL;
+ vlog.debug("initialisation done");
+ }
// getCSecurity() gets the CSecurity object for the given type. The type
// is guaranteed to be one of the secTypes passed in to addSecType(). The
@@ -286,16 +321,6 @@ abstract public class CConnection extends CMsgHandler {
clientSecTypeOrder = csto;
}
- // authSuccess() is called when authentication has succeeded.
- public void authSuccess() {}
-
- // serverInit() is called when the ServerInit message is received. The
- // derived class must call on to CConnection::serverInit().
- public void serverInit() {
- state_ = RFBSTATE_NORMAL;
- vlog.debug("initialisation done");
- }
-
// Other methods
public CMsgReaderV3 reader() { return reader_; }
@@ -318,7 +343,22 @@ abstract public class CConnection extends CMsgHandler {
public int state() { return state_; }
- protected void setState(int s) { state_ = s; }
+ protected final void setState(int s) { state_ = s; }
+
+ public void fence(int flags, int len, byte[] data)
+ {
+ super.fence(flags, len, data);
+
+ if ((flags & fenceTypes.fenceFlagRequest) != 0)
+ return;
+
+ // We cannot guarantee any synchronisation at this level
+ flags = 0;
+
+ synchronized(this) {
+ writer().writeFence(flags, len, data);
+ }
+ }
private void throwAuthFailureException() {
String reason;
@@ -333,11 +373,11 @@ abstract public class CConnection extends CMsgHandler {
throw new AuthFailureException(reason);
}
- InStream is = null;
- OutStream os = null;
- CMsgReaderV3 reader_ = null;
- CMsgWriterV3 writer_ = null;
- boolean shared = false;
+ InStream is;
+ OutStream os;
+ CMsgReaderV3 reader_;
+ CMsgWriterV3 writer_;
+ boolean shared;
public CSecurity csecurity;
public SecurityClient security;
public static final int maxSecTypes = 8;
@@ -346,7 +386,7 @@ abstract public class CConnection extends CMsgHandler {
int state_ = RFBSTATE_UNINITIALISED;
String serverName;
int serverPort;
- boolean useProtocol3_3 = false;
+ boolean useProtocol3_3;
boolean clientSecTypeOrder;
static LogWriter vlog = new LogWriter("CConnection");
diff --git a/java/com/tigervnc/rfb/ConnParams.java b/java/com/tigervnc/rfb/ConnParams.java
index e3c3a824..08037231 100644
--- a/java/com/tigervnc/rfb/ConnParams.java
+++ b/java/com/tigervnc/rfb/ConnParams.java
@@ -47,6 +47,7 @@ public class ConnParams {
{
if (verStrPos >= 12) return false;
verStr = new StringBuilder(13);
+ is.check(12);
while (verStrPos < 12) {
verStr.insert(verStrPos++,(char)is.readU8());
}
diff --git a/java/com/tigervnc/vncviewer/CConn.java b/java/com/tigervnc/vncviewer/CConn.java
index d4ef5e90..061e6fbe 100644
--- a/java/com/tigervnc/vncviewer/CConn.java
+++ b/java/com/tigervnc/vncviewer/CConn.java
@@ -530,7 +530,8 @@ public class CConn extends CConnection
public void fence(int flags, int len, byte[] data)
{
- super.fence(flags, len, data);
+ // can't call super.super.fence(flags, len, data);
+ cp.supportsFence = true;
if ((flags & fenceTypes.fenceFlagRequest) != 0) {
// We handle everything synchronously so we trivially honor these modes