1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
package com.juick.xmpp.s2s;
import com.juick.xmpp.utils.XmlUtils;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.Channels;
import org.xmlpull.v1.XmlPullParser;
/**
*
* @author ugnich
*/
public class ConnectionOut extends Connection implements Runnable {
public boolean streamReady = false;
public String to;
String checkSID = null;
String dbKey = null;
public ConnectionOut(String hostname) {
super();
to = hostname;
}
public ConnectionOut(String hostname, String checkSID, String dbKey) {
super();
to = hostname;
this.checkSID = checkSID;
this.dbKey = dbKey;
}
@Override
public void run() {
LOGGER.info("STREAM TO " + to + " START");
try {
HostnamePort addr = DNSQueries.getServerAddress(to);
socket = AsynchronousSocketChannel.open();
socket.connect(new InetSocketAddress(addr.hostname, addr.port));
parser.setInput(new InputStreamReader(Channels.newInputStream(socket)));
writer = new OutputStreamWriter(Channels.newOutputStream(socket));
sendStanza("<?xml version='1.0'?><stream:stream xmlns='jabber:server' " +
"xmlns:stream='http://etherx.jabber.org/streams' xmlns:db='jabber:server:dialback' from='" +
XMPPComponent.HOSTNAME + "' to='" + to + "' version='1.0'>");
parser.next(); // stream:stream
streamID = parser.getAttributeValue(null, "id");
if (streamID == null || streamID.isEmpty()) {
throw new Exception("STREAM TO " + to + " INVALID FIRST PACKET");
}
LOGGER.info("STREAM TO " + to + " " + streamID + " OPEN");
XMPPComponent.addConnectionOut(this);
if (checkSID != null) {
sendDialbackVerify(checkSID, dbKey);
}
sendStanza("<db:result from='" + XMPPComponent.HOSTNAME + "' to='" + to + "'>" + generateDialbackKey(to, XMPPComponent.HOSTNAME, streamID) + "</db:result>");
while (parser.next() != XmlPullParser.END_DOCUMENT) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
logParser();
String tag = parser.getName();
if (tag.equals("db:result")) {
String type = parser.getAttributeValue(null, "type");
if (type != null && type.equals("valid")) {
streamReady = true;
LOGGER.info("STREAM TO " + to + " " + streamID + " READY");
String cache = XMPPComponent.getFromCache(to);
if (cache != null) {
LOGGER.info("STREAM TO " + to + " " + streamID + " SENDING CACHE");
sendStanza(cache);
}
} else {
LOGGER.info("STREAM TO " + to + " " + streamID + " DIALBACK FAIL");
}
XmlUtils.skip(parser);
} else if (tag.equals("db:verify")) {
String from = parser.getAttributeValue(null, "from");
String type = parser.getAttributeValue(null, "type");
String sid = parser.getAttributeValue(null, "id");
if (from != null && from.equals(to) && sid != null && !sid.isEmpty() && type != null) {
ConnectionIn c = XMPPComponent.getConnectionIn(sid);
if (c != null) {
c.sendDialbackResult(from, type);
}
}
XmlUtils.skip(parser);
} else {
LOGGER.info("STREAM TO " + to + " " + streamID + ": " + XmlUtils.parseToString(parser, true));
}
}
LOGGER.warning("STREAM TO " + to + " " + streamID + " FINISHED");
XMPPComponent.removeConnectionOut(this);
closeConnection();
} catch (Exception e) {
LOGGER.warning(e.toString());
XMPPComponent.removeConnectionOut(this);
closeConnection();
}
}
public void sendDialbackVerify(String sid, String key) {
try {
sendStanza("<db:verify from='" + XMPPComponent.HOSTNAME + "' to='" + to + "' id='" + sid + "'>" + key + "</db:verify>");
} catch (IOException e) {
LOGGER.warning("STREAM TO " + to + " " + streamID + " ERROR: " + e.toString());
}
}
}
|