83 /** |
83 /** |
84 * Are we using an older DatagramSocketImpl? |
84 * Are we using an older DatagramSocketImpl? |
85 */ |
85 */ |
86 boolean oldImpl = false; |
86 boolean oldImpl = false; |
87 |
87 |
|
88 /** |
|
89 * Set when a socket is ST_CONNECTED until we are certain |
|
90 * that any packets which might have been received prior |
|
91 * to calling connect() but not read by the application |
|
92 * have been read. During this time we check the source |
|
93 * address of all packets received to be sure they are from |
|
94 * the connected destination. Other packets are read but |
|
95 * silently dropped. |
|
96 */ |
|
97 private boolean explicitFilter = false; |
|
98 private int bytesLeftToFilter; |
88 /* |
99 /* |
89 * Connection state: |
100 * Connection state: |
90 * ST_NOT_CONNECTED = socket not connected |
101 * ST_NOT_CONNECTED = socket not connected |
91 * ST_CONNECTED = socket connected |
102 * ST_CONNECTED = socket connected |
92 * ST_CONNECTED_NO_IMPL = socket connected but not at impl level |
103 * ST_CONNECTED_NO_IMPL = socket connected but not at impl level |
142 try { |
153 try { |
143 getImpl().connect(address, port); |
154 getImpl().connect(address, port); |
144 |
155 |
145 // socket is now connected by the impl |
156 // socket is now connected by the impl |
146 connectState = ST_CONNECTED; |
157 connectState = ST_CONNECTED; |
|
158 // Do we need to filter some packets? |
|
159 int avail = getImpl().dataAvailable(); |
|
160 if (avail == -1) { |
|
161 throw new SocketException(); |
|
162 } |
|
163 explicitFilter = avail > 0; |
|
164 if (explicitFilter) { |
|
165 bytesLeftToFilter = getReceiveBufferSize(); |
|
166 } |
147 } catch (SocketException se) { |
167 } catch (SocketException se) { |
148 |
168 |
149 // connection will be emulated by DatagramSocket |
169 // connection will be emulated by DatagramSocket |
150 connectState = ST_CONNECTED_NO_IMPL; |
170 connectState = ST_CONNECTED_NO_IMPL; |
151 } |
171 } |
748 continue; |
769 continue; |
749 } |
770 } |
750 } // end of while |
771 } // end of while |
751 } |
772 } |
752 } |
773 } |
753 if (connectState == ST_CONNECTED_NO_IMPL) { |
774 if ((connectState == ST_CONNECTED_NO_IMPL) || explicitFilter) { |
754 // We have to do the filtering the old fashioned way since |
775 // We have to do the filtering the old fashioned way since |
755 // the native impl doesn't support connect or the connect |
776 // the native impl doesn't support connect or the connect |
756 // via the impl failed. |
777 // via the impl failed, or .. "explicitFilter" may be set when |
|
778 // a socket is connected via the impl, for a period of time |
|
779 // when packets from other sources might be queued on socket. |
757 boolean stop = false; |
780 boolean stop = false; |
758 while (!stop) { |
781 while (!stop) { |
759 InetAddress peekAddress = null; |
782 InetAddress peekAddress = null; |
760 int peekPort = -1; |
783 int peekPort = -1; |
761 // peek at the packet to see who it is from. |
784 // peek at the packet to see who it is from. |
770 peekPort = getImpl().peek(peekAddress); |
793 peekPort = getImpl().peek(peekAddress); |
771 } |
794 } |
772 if ((!connectedAddress.equals(peekAddress)) || |
795 if ((!connectedAddress.equals(peekAddress)) || |
773 (connectedPort != peekPort)) { |
796 (connectedPort != peekPort)) { |
774 // throw the packet away and silently continue |
797 // throw the packet away and silently continue |
775 DatagramPacket tmp = new DatagramPacket(new byte[1], 1); |
798 DatagramPacket tmp = new DatagramPacket( |
|
799 new byte[1024], 1024); |
776 getImpl().receive(tmp); |
800 getImpl().receive(tmp); |
|
801 if (explicitFilter) { |
|
802 bytesLeftToFilter -= tmp.getLength(); |
|
803 } |
777 } else { |
804 } else { |
778 stop = true; |
805 stop = true; |
779 } |
806 } |
780 } |
807 } |
781 } |
808 } |
782 // If the security check succeeds, or the datagram is |
809 // If the security check succeeds, or the datagram is |
783 // connected then receive the packet |
810 // connected then receive the packet |
784 getImpl().receive(p); |
811 getImpl().receive(p); |
|
812 if (explicitFilter) { |
|
813 bytesLeftToFilter -= p.getLength(); |
|
814 if (bytesLeftToFilter <= 0) { |
|
815 explicitFilter = false; |
|
816 } else { |
|
817 // break out of filter, if there is no more data queued |
|
818 explicitFilter = getImpl().dataAvailable() > 0; |
|
819 } |
|
820 } |
785 } |
821 } |
786 } |
822 } |
787 |
823 |
788 /** |
824 /** |
789 * Gets the local address to which the socket is bound. |
825 * Gets the local address to which the socket is bound. |