Revision: 4871 http://tigervnc.svn.sourceforge.net/tigervnc/?rev=4871&view=rev Author: bphinz Date: 2012-03-18 21:39:04 +0000 (Sun, 18 Mar 2012) Log Message: ----------- Changes aimed at making the behavior of the java client more consistent with the binary client.
Modified Paths: -------------- trunk/java/com/tigervnc/network/FileDescriptor.java trunk/java/com/tigervnc/network/SocketDescriptor.java trunk/java/com/tigervnc/rdr/FdInStream.java trunk/java/com/tigervnc/rdr/FdOutStream.java trunk/java/com/tigervnc/rdr/InStream.java trunk/java/com/tigervnc/rfb/CConnection.java trunk/java/com/tigervnc/rfb/ConnParams.java trunk/java/com/tigervnc/vncviewer/CConn.java Modified: trunk/java/com/tigervnc/network/FileDescriptor.java =================================================================== --- trunk/java/com/tigervnc/network/FileDescriptor.java 2012-03-16 03:16:42 UTC (rev 4870) +++ trunk/java/com/tigervnc/network/FileDescriptor.java 2012-03-18 21:39:04 UTC (rev 4871) @@ -25,7 +25,7 @@ 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; } Modified: trunk/java/com/tigervnc/network/SocketDescriptor.java =================================================================== --- trunk/java/com/tigervnc/network/SocketDescriptor.java 2012-03-16 03:16:42 UTC (rev 4870) +++ trunk/java/com/tigervnc/network/SocketDescriptor.java 2012-03-18 21:39:04 UTC (rev 4871) @@ -88,32 +88,37 @@ 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 { Modified: trunk/java/com/tigervnc/rdr/FdInStream.java =================================================================== --- trunk/java/com/tigervnc/rdr/FdInStream.java 2012-03-16 03:16:42 UTC (rev 4870) +++ trunk/java/com/tigervnc/rdr/FdInStream.java 2012-03-18 21:39:04 UTC (rev 4871) @@ -27,22 +27,37 @@ 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; - timeoutms = 0; - timing = false; - timeWaitedIn100us = 5; - timedKbits = 0; } - public FdInStream(FileDescriptor fd_) { this(fd_, defaultBufSize); } + 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; + } + + public FdInStream(FileDescriptor fd_, + FdInStreamBlockCallback blockCallback_) { + this(fd_, blockCallback_, 0); + } + public final void readBytes(byte[] data, int dataPtr, int length) { if (length < minBulkSize) { super.readBytes(data, dataPtr, length); @@ -100,7 +115,8 @@ 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 @@ 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; - } + if (!wait) { + tv = new Integer(0); + } else if (timeoutms != -1) { + tv = new Integer(timeoutms); + } else { + tv = null; + } - try { - n = fd.select(SelectionKey.OP_READ, timeout); - } catch (Exception e) { - throw new SystemException("select:"+e.toString()); - } + 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 @@ fd = fd_; } + private FileDescriptor fd; + boolean closeWhenDone; + protected int timeoutms; + private FdInStreamBlockCallback blockCallback; private int offset; private int bufSize; - private FileDescriptor fd; - private FdInStreamBlockCallback blockCallback; - protected int timeoutms; protected boolean timing; protected long timeWaitedIn100us; Modified: trunk/java/com/tigervnc/rdr/FdOutStream.java =================================================================== --- trunk/java/com/tigervnc/rdr/FdOutStream.java 2012-03-16 03:16:42 UTC (rev 4870) +++ trunk/java/com/tigervnc/rdr/FdOutStream.java 2012-03-18 21:39:04 UTC (rev 4871) @@ -24,22 +24,20 @@ 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 @@ 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 @@ } while (n < 0); + if (n == 0) return 0; + try { n = fd.write(data, dataPtr, length); } catch (java.lang.Exception e) { Modified: trunk/java/com/tigervnc/rdr/InStream.java =================================================================== --- trunk/java/com/tigervnc/rdr/InStream.java 2012-03-16 03:16:42 UTC (rev 4870) +++ trunk/java/com/tigervnc/rdr/InStream.java 2012-03-18 21:39:04 UTC (rev 4871) @@ -32,12 +32,11 @@ // 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 @@ // 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 @@ 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 @@ 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 @@ 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; } Modified: trunk/java/com/tigervnc/rfb/CConnection.java =================================================================== --- trunk/java/com/tigervnc/rfb/CConnection.java 2012-03-16 03:16:42 UTC (rev 4870) +++ trunk/java/com/tigervnc/rfb/CConnection.java 2012-03-18 21:39:04 UTC (rev 4871) @@ -25,31 +25,37 @@ 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 @@ } } - 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 @@ } 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 @@ 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 @@ 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 @@ 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 @@ * 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 @@ 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 @@ // 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,16 +286,23 @@ 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 // CSecurity object's destroy() method will be called by the CConnection @@ -286,16 +321,6 @@ 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,8 +343,23 @@ 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; vlog.debug("state="+state()+", ver="+cp.majorVersion+"."+cp.minorVersion); @@ -333,11 +373,11 @@ 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 @@ int state_ = RFBSTATE_UNINITIALISED; String serverName; int serverPort; - boolean useProtocol3_3 = false; + boolean useProtocol3_3; boolean clientSecTypeOrder; static LogWriter vlog = new LogWriter("CConnection"); Modified: trunk/java/com/tigervnc/rfb/ConnParams.java =================================================================== --- trunk/java/com/tigervnc/rfb/ConnParams.java 2012-03-16 03:16:42 UTC (rev 4870) +++ trunk/java/com/tigervnc/rfb/ConnParams.java 2012-03-18 21:39:04 UTC (rev 4871) @@ -47,6 +47,7 @@ { if (verStrPos >= 12) return false; verStr = new StringBuilder(13); + is.check(12); while (verStrPos < 12) { verStr.insert(verStrPos++,(char)is.readU8()); } Modified: trunk/java/com/tigervnc/vncviewer/CConn.java =================================================================== --- trunk/java/com/tigervnc/vncviewer/CConn.java 2012-03-16 03:16:42 UTC (rev 4870) +++ trunk/java/com/tigervnc/vncviewer/CConn.java 2012-03-18 21:39:04 UTC (rev 4871) @@ -530,7 +530,8 @@ 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 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------------ This SF email is sponsosred by: Try Windows Azure free for 90 days Click Here http://p.sf.net/sfu/sfd2d-msazure _______________________________________________ Tigervnc-commits mailing list Tigervnc-commits@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/tigervnc-commits