|
@@ -21,7 +21,7 @@
|
21
|
21
|
*/
|
22
|
22
|
package com.dmdirc.parser.irc;
|
23
|
23
|
|
24
|
|
-import com.dmdirc.parser.common.BaseParser;
|
|
24
|
+import com.dmdirc.parser.common.BaseSocketAwareParser;
|
25
|
25
|
import com.dmdirc.parser.common.ChannelJoinRequest;
|
26
|
26
|
import com.dmdirc.parser.common.ChildImplementations;
|
27
|
27
|
import com.dmdirc.parser.common.CompositionState;
|
|
@@ -53,8 +53,6 @@ import java.io.IOException;
|
53
|
53
|
import java.net.Inet4Address;
|
54
|
54
|
import java.net.Inet6Address;
|
55
|
55
|
import java.net.InetAddress;
|
56
|
|
-import java.net.InetSocketAddress;
|
57
|
|
-import java.net.Proxy;
|
58
|
56
|
import java.net.Socket;
|
59
|
57
|
import java.net.URI;
|
60
|
58
|
import java.net.URISyntaxException;
|
|
@@ -92,7 +90,7 @@ import javax.net.ssl.X509TrustManager;
|
92
|
90
|
IRCChannelInfo.class,
|
93
|
91
|
IRCClientInfo.class
|
94
|
92
|
})
|
95
|
|
-public class IRCParser extends BaseParser implements SecureParser, EncodingParser {
|
|
93
|
+public class IRCParser extends BaseSocketAwareParser implements SecureParser, EncodingParser {
|
96
|
94
|
|
97
|
95
|
/** Max length an outgoing line should be (NOT including \r\n). */
|
98
|
96
|
public static final int MAX_LINELENGTH = 510;
|
|
@@ -164,8 +162,6 @@ public class IRCParser extends BaseParser implements SecureParser, EncodingParse
|
164
|
162
|
boolean post005;
|
165
|
163
|
/** Has the thread started execution yet, (Prevents run() being called multiple times). */
|
166
|
164
|
boolean hasBegan;
|
167
|
|
- /** Connect timeout. */
|
168
|
|
- private int connectTimeout = 5000;
|
169
|
165
|
/** Manager used to handle prefix modes. */
|
170
|
166
|
public final PrefixModeManager prefixModes = new PrefixModeManager();
|
171
|
167
|
/** Manager used to handle user modes (owxis etc). */
|
|
@@ -480,24 +476,6 @@ public class IRCParser extends BaseParser implements SecureParser, EncodingParse
|
480
|
476
|
addLastLine = newValue;
|
481
|
477
|
}
|
482
|
478
|
|
483
|
|
- /**
|
484
|
|
- * Get the current Value of connectTimeout.
|
485
|
|
- *
|
486
|
|
- * @return The value of getConnectTimeout.
|
487
|
|
- */
|
488
|
|
- public int getConnectTimeout() {
|
489
|
|
- return connectTimeout;
|
490
|
|
- }
|
491
|
|
-
|
492
|
|
- /**
|
493
|
|
- * Set the Value of connectTimeout.
|
494
|
|
- *
|
495
|
|
- * @param newValue new value for value of getConnectTimeout.
|
496
|
|
- */
|
497
|
|
- public void setConnectTimeout(final int newValue) {
|
498
|
|
- connectTimeout = newValue;
|
499
|
|
- }
|
500
|
|
-
|
501
|
479
|
/**
|
502
|
480
|
* Get the current socket State.
|
503
|
481
|
*
|
|
@@ -753,85 +731,6 @@ public class IRCParser extends BaseParser implements SecureParser, EncodingParse
|
753
|
731
|
disconnectOnFatal = newValue;
|
754
|
732
|
}
|
755
|
733
|
|
756
|
|
- /**
|
757
|
|
- * Create a new Socket object for the given target, using the given proxy
|
758
|
|
- * if appropriate.
|
759
|
|
- *
|
760
|
|
- * @param target Target URI to connect to.
|
761
|
|
- * @param proxy Proxy URI to use
|
762
|
|
- * @return Socket, with IP Binding or Proxy as appropriate,
|
763
|
|
- * @throws IOException If there was an issue creating the socket.
|
764
|
|
- */
|
765
|
|
- private Socket newSocket(final URI target, final URI proxy) throws IOException {
|
766
|
|
- if (target.getPort() > 65535 || target.getPort() <= 0) {
|
767
|
|
- throw new IOException("Server port (" + target.getPort() + ") is invalid.");
|
768
|
|
- }
|
769
|
|
-
|
770
|
|
- final Socket mySocket;
|
771
|
|
- if (proxy == null) {
|
772
|
|
- callDebugInfo(DEBUG_SOCKET, "Not using Proxy");
|
773
|
|
- mySocket = new Socket();
|
774
|
|
-
|
775
|
|
- final InetSocketAddress sockAddr = new InetSocketAddress(target.getHost(), target.getPort());
|
776
|
|
-
|
777
|
|
- if (sockAddr.getAddress() instanceof Inet6Address) {
|
778
|
|
- if (getBindIPv6() != null && !getBindIPv6().isEmpty()) {
|
779
|
|
- callDebugInfo(DEBUG_SOCKET, "Binding to IPv6: " + getBindIPv6());
|
780
|
|
- try {
|
781
|
|
- mySocket.bind(new InetSocketAddress(InetAddress.getByName(getBindIPv6()), 0));
|
782
|
|
- } catch (IOException e) {
|
783
|
|
- callDebugInfo(DEBUG_SOCKET, "Binding failed: " + e.getMessage());
|
784
|
|
- }
|
785
|
|
- }
|
786
|
|
- } else {
|
787
|
|
- if (getBindIP() != null && !getBindIP().isEmpty()) {
|
788
|
|
- callDebugInfo(DEBUG_SOCKET, "Binding to IPv4: " + getBindIP());
|
789
|
|
- try {
|
790
|
|
- mySocket.bind(new InetSocketAddress(InetAddress.getByName(getBindIP()), 0));
|
791
|
|
- } catch (IOException e) {
|
792
|
|
- callDebugInfo(DEBUG_SOCKET, "Binding failed: " + e.getMessage());
|
793
|
|
- }
|
794
|
|
- }
|
795
|
|
- }
|
796
|
|
-
|
797
|
|
- mySocket.connect(sockAddr, connectTimeout);
|
798
|
|
- } else {
|
799
|
|
- callDebugInfo(DEBUG_SOCKET, "Using Proxy");
|
800
|
|
-
|
801
|
|
- if (getBindIP() != null && !getBindIP().isEmpty() ||
|
802
|
|
- getBindIPv6() != null && !getBindIPv6().isEmpty()) {
|
803
|
|
- callDebugInfo(DEBUG_SOCKET, "IP Binding is not possible when using a proxy.");
|
804
|
|
- }
|
805
|
|
-
|
806
|
|
- final String proxyHost = proxy.getHost();
|
807
|
|
- final int proxyPort = proxy.getPort();
|
808
|
|
-
|
809
|
|
- if (proxyPort > 65535 || proxyPort <= 0) {
|
810
|
|
- throw new IOException("Proxy port (" + proxyPort + ") is invalid.");
|
811
|
|
- }
|
812
|
|
-
|
813
|
|
- final Proxy.Type proxyType = Proxy.Type.valueOf(proxy.getScheme().toUpperCase());
|
814
|
|
- mySocket = new Socket(new Proxy(proxyType, new InetSocketAddress(proxyHost, proxyPort)));
|
815
|
|
-
|
816
|
|
- final IRCAuthenticator ia = IRCAuthenticator.getIRCAuthenticator();
|
817
|
|
-
|
818
|
|
- try {
|
819
|
|
- try {
|
820
|
|
- ia.getSemaphore().acquire();
|
821
|
|
- } catch (InterruptedException ex) {
|
822
|
|
- }
|
823
|
|
-
|
824
|
|
- ia.addAuthentication(target, proxy);
|
825
|
|
- mySocket.connect(new InetSocketAddress(target.getHost(), target.getPort()), connectTimeout);
|
826
|
|
- } finally {
|
827
|
|
- ia.removeAuthentication(target, proxy);
|
828
|
|
- ia.getSemaphore().release();
|
829
|
|
- }
|
830
|
|
- }
|
831
|
|
-
|
832
|
|
- return mySocket;
|
833
|
|
- }
|
834
|
|
-
|
835
|
734
|
/**
|
836
|
735
|
* Find a socket to connect using, this will where possible attempt IPv6
|
837
|
736
|
* first, before falling back to IPv4.
|
|
@@ -849,18 +748,17 @@ public class IRCParser extends BaseParser implements SecureParser, EncodingParse
|
849
|
748
|
* will cause a double-length connection timeout.
|
850
|
749
|
*
|
851
|
750
|
* @param target Target URI to connect to.
|
852
|
|
- * @param proxy Proxy URI to use
|
853
|
751
|
* @return Socket to use in future connections.
|
854
|
752
|
* @throws IOException if there is an error.
|
855
|
753
|
*/
|
856
|
|
- private Socket findSocket(final URI target, final URI proxy) throws IOException {
|
857
|
|
- if (proxy != null) {
|
|
754
|
+ private Socket findSocket(final URI target) throws IOException {
|
|
755
|
+ if (getProxy() != null) {
|
858
|
756
|
// If we have a proxy, let it worry about all this instead.
|
859
|
757
|
//
|
860
|
758
|
// 1) We have no idea what sort of connectivity the proxy has
|
861
|
759
|
// 2) If we do this here, then any DNS-based geo-balancing is
|
862
|
760
|
// going to be based on our location, not the proxy.
|
863
|
|
- return newSocket(target, proxy);
|
|
761
|
+ return getSocketFactory().createSocket(target.getHost(), target.getPort());
|
864
|
762
|
}
|
865
|
763
|
|
866
|
764
|
URI target6 = null;
|
|
@@ -894,7 +792,7 @@ public class IRCParser extends BaseParser implements SecureParser, EncodingParse
|
894
|
792
|
Exception v6Exception = null;
|
895
|
793
|
if (target6 != null) {
|
896
|
794
|
try {
|
897
|
|
- return newSocket(target6, null);
|
|
795
|
+ return getSocketFactory().createSocket(target6.getHost(), target6.getPort());
|
898
|
796
|
} catch (final IOException ioe) {
|
899
|
797
|
if (target4 == null) {
|
900
|
798
|
throw ioe;
|
|
@@ -906,7 +804,7 @@ public class IRCParser extends BaseParser implements SecureParser, EncodingParse
|
906
|
804
|
}
|
907
|
805
|
if (target4 != null) {
|
908
|
806
|
try {
|
909
|
|
- return newSocket(target4, null);
|
|
807
|
+ return getSocketFactory().createSocket(target4.getHost(), target4.getPort());
|
910
|
808
|
} catch (final IOException e2) {
|
911
|
809
|
callDebugInfo(DEBUG_SOCKET, "Exception trying to use IPv4: " + e2);
|
912
|
810
|
throw e2;
|
|
@@ -936,7 +834,7 @@ public class IRCParser extends BaseParser implements SecureParser, EncodingParse
|
936
|
834
|
callDebugInfo(DEBUG_SOCKET, "Connecting to " + getURI().getHost() + ':' + getURI().getPort());
|
937
|
835
|
|
938
|
836
|
currentSocketState = SocketState.OPENING;
|
939
|
|
- socket = findSocket(getConnectURI(getURI()), getProxy());
|
|
837
|
+ socket = findSocket(getConnectURI(getURI()));
|
940
|
838
|
|
941
|
839
|
rawSocket = socket;
|
942
|
840
|
|
|
@@ -1063,15 +961,6 @@ public class IRCParser extends BaseParser implements SecureParser, EncodingParse
|
1063
|
961
|
callDebugInfo(DEBUG_INFO, "End Thread Execution");
|
1064
|
962
|
}
|
1065
|
963
|
|
1066
|
|
- @Override
|
1067
|
|
- public int getLocalPort() {
|
1068
|
|
- if (currentSocketState == SocketState.OPENING || currentSocketState == SocketState.OPEN) {
|
1069
|
|
- return socket.getLocalPort();
|
1070
|
|
- } else {
|
1071
|
|
- return 0;
|
1072
|
|
- }
|
1073
|
|
- }
|
1074
|
|
-
|
1075
|
964
|
/** Close socket on destroy. */
|
1076
|
965
|
@Override
|
1077
|
966
|
protected void finalize() throws Throwable {
|
|
@@ -2340,4 +2229,10 @@ public class IRCParser extends BaseParser implements SecureParser, EncodingParse
|
2340
|
2229
|
public void setCompositionState(final String host, final CompositionState state) {
|
2341
|
2230
|
// Do nothing
|
2342
|
2231
|
}
|
|
2232
|
+
|
|
2233
|
+ @Override
|
|
2234
|
+ protected void handleSocketDebug(final String message) {
|
|
2235
|
+ super.handleSocketDebug(message);
|
|
2236
|
+ callDebugInfo(DEBUG_SOCKET, message);
|
|
2237
|
+ }
|
2343
|
2238
|
}
|