Compare commits
4 Commits
master
...
catch-disc
Author | SHA1 | Date |
---|---|---|
Xavier Del Campo Romero | 44c5ea24fa | |
Xavier Del Campo Romero | 26844a2b70 | |
Xavier Del Campo Romero | e0417a8a4d | |
Xavier Del Campo Romero | 946d113aad |
|
@ -74,6 +74,7 @@ public class Conversation : Object {
|
|||
notify_setting = (NotifySetting) row[db.conversation.notification];
|
||||
send_typing = (Setting) row[db.conversation.send_typing];
|
||||
send_marker = (Setting) row[db.conversation.send_marker];
|
||||
debug(@"account=$(account.display_name),encryption=$(encryption),resource=$(resource ?? "null")");
|
||||
|
||||
notify.connect(on_update);
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ public class ConnectionManager : Object {
|
|||
|
||||
private HashMap<Account, Connection> connections = new HashMap<Account, Connection>(Account.hash_func, Account.equals_func);
|
||||
private HashMap<Account, ConnectionError> connection_errors = new HashMap<Account, ConnectionError>(Account.hash_func, Account.equals_func);
|
||||
private HashMap<Account, string> session_ids = new HashMap<Account, string>(Account.hash_func, Account.equals_func);
|
||||
private NetworkMonitor? network_monitor;
|
||||
private ModuleManager module_manager;
|
||||
public string? log_options;
|
||||
|
@ -64,7 +65,11 @@ public class ConnectionManager : Object {
|
|||
if (stream != null) {
|
||||
stream.detach_modules();
|
||||
|
||||
yield stream.disconnect();
|
||||
try {
|
||||
yield stream.disconnect();
|
||||
} catch (IOError e) {
|
||||
warning(@"caught IOError: $(e.message)");
|
||||
}
|
||||
}
|
||||
stream = null;
|
||||
uuid = Xmpp.random_uuid();
|
||||
|
@ -159,7 +164,7 @@ public class ConnectionManager : Object {
|
|||
public async void disconnect_account(Account account) {
|
||||
if (connections.has_key(account)) {
|
||||
make_offline(account);
|
||||
connections[account].disconnect_account.begin();
|
||||
yield connections[account].disconnect_account();
|
||||
connections.unset(account);
|
||||
}
|
||||
}
|
||||
|
@ -180,7 +185,6 @@ public class ConnectionManager : Object {
|
|||
change_connection_state(account, ConnectionState.DISCONNECTED);
|
||||
return on_invalid_certificate(account.domainpart, peer_cert, errors); }
|
||||
);
|
||||
connections[account].stream = stream_result.stream;
|
||||
|
||||
if (stream_result.stream == null) {
|
||||
if (stream_result.tls_errors != null) {
|
||||
|
@ -188,7 +192,7 @@ public class ConnectionManager : Object {
|
|||
return;
|
||||
}
|
||||
|
||||
debug("[%s] Could not connect", account.bare_jid.to_string());
|
||||
warning("[%s] Could not connect", account.bare_jid.to_string());
|
||||
|
||||
change_connection_state(account, ConnectionState.DISCONNECTED);
|
||||
|
||||
|
@ -197,7 +201,18 @@ public class ConnectionManager : Object {
|
|||
|
||||
XmppStream stream = stream_result.stream;
|
||||
|
||||
debug("[%s] New connection with resource %s: %p", account.bare_jid.to_string(), resource, stream);
|
||||
print("[%s] New connection with resource %s: %p\n", account.bare_jid.to_string(), resource, stream);
|
||||
|
||||
var? module = stream.get_module(Xep.StreamManagement.Module.IDENTITY);
|
||||
if (module != null) {
|
||||
if (session_ids[account] != null) {
|
||||
module.session_id = session_ids[account];
|
||||
}
|
||||
|
||||
module.got_session_id.connect((session_id) => {
|
||||
session_ids[account] = session_id;
|
||||
});
|
||||
}
|
||||
|
||||
stream.attached_modules.connect((stream) => {
|
||||
stream_attached_modules(account, stream);
|
||||
|
@ -216,6 +231,7 @@ public class ConnectionManager : Object {
|
|||
warning("Got node for outdated connection");
|
||||
}
|
||||
});
|
||||
connections[account].stream = stream_result.stream;
|
||||
stream_opened(account, stream);
|
||||
|
||||
try {
|
||||
|
@ -224,7 +240,7 @@ public class ConnectionManager : Object {
|
|||
debug("[%s %p] Connection error: %s", account.bare_jid.to_string(), stream, e.message);
|
||||
|
||||
change_connection_state(account, ConnectionState.DISCONNECTED);
|
||||
connections[account].reset();
|
||||
yield connections[account].reset();
|
||||
|
||||
StreamError.Flag? flag = stream.get_flag(StreamError.Flag.IDENTITY);
|
||||
if (flag != null) {
|
||||
|
@ -252,13 +268,14 @@ public class ConnectionManager : Object {
|
|||
}
|
||||
}
|
||||
|
||||
private void check_ping_reconnect(Xmpp.Xep.Ping.Module identity,
|
||||
XmppStream stream, Account account) {
|
||||
identity.send_ping.begin(stream, account.bare_jid.domain_jid, () => {
|
||||
if (connections[account].stream != stream) return;
|
||||
connections[account].acked = true;
|
||||
change_connection_state(account, ConnectionState.CONNECTED);
|
||||
});
|
||||
private async void check_ping_reconnect(Account account) {
|
||||
yield connections[account].reset();
|
||||
yield connect_stream(account);
|
||||
|
||||
XmppStream stream = connections[account].stream;
|
||||
|
||||
var? identity = stream.get_module(Xep.Ping.Module.IDENTITY);
|
||||
if (identity == null) return;
|
||||
|
||||
Timeout.add_seconds(10, () => {
|
||||
if (!connections.has_key(account)) return false;
|
||||
|
@ -266,16 +283,29 @@ public class ConnectionManager : Object {
|
|||
if (connections[account].acked) return false;
|
||||
|
||||
// Reconnect. Nothing gets through the stream.
|
||||
debug("[%s %p] Ping timeouted. Reconnecting", account.bare_jid.to_string(), stream);
|
||||
warning("[%s %p] Ping timeouted. Reconnecting", account.bare_jid.to_string(), stream);
|
||||
change_connection_state(account, ConnectionState.DISCONNECTED);
|
||||
|
||||
connections[account].reset();
|
||||
connect_stream.begin(account);
|
||||
connections[account].reset.begin((_, res) => {
|
||||
connections[account].reset.end(res);
|
||||
connect_stream.begin(account);
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
yield identity.send_ping(stream, account.bare_jid.domain_jid);
|
||||
|
||||
connections[account].acked = true;
|
||||
change_connection_state(account, ConnectionState.CONNECTED);
|
||||
|
||||
var? module = stream.get_module(Xep.StreamManagement.Module.IDENTITY);
|
||||
if (module != null) {
|
||||
module.session_id = session_ids[account];
|
||||
stream.require_setup();
|
||||
}
|
||||
}
|
||||
|
||||
private void check_reconnect(Account account, bool directly_reconnect = false) {
|
||||
private void check_reconnect(Account account) {
|
||||
if (!connections.has_key(account)) return;
|
||||
|
||||
var cancellable = new Cancellable();
|
||||
|
@ -288,27 +318,27 @@ public class ConnectionManager : Object {
|
|||
debug(@"can-reach: $(reachable)");
|
||||
|
||||
if (reachable) {
|
||||
Xmpp.Xep.Ping.Module? identity = null;
|
||||
if (connections[account].connection_state == ConnectionState.CONNECTING) return;
|
||||
|
||||
XmppStream? stream = connections[account].stream;
|
||||
connections[account].acked = false;
|
||||
|
||||
if (stream != null
|
||||
&& (identity = stream.get_module(Xep.Ping.Module.IDENTITY)) != null) {
|
||||
if (stream != null) {
|
||||
change_connection_state(account, ConnectionState.CONNECTING);
|
||||
check_ping_reconnect(identity, stream, account);
|
||||
check_ping_reconnect.begin(account);
|
||||
}
|
||||
else {
|
||||
change_connection_state(account, ConnectionState.DISCONNECTED);
|
||||
|
||||
connections[account].reset();
|
||||
connect_stream.begin(account);
|
||||
connections[account].reset.begin((_, res) => {
|
||||
connections[account].reset.end(res);
|
||||
connect_stream.begin(account);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Error e) {
|
||||
print ("Error: %s\n", e.message);
|
||||
warning(@"$(e.message)");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -88,7 +88,17 @@ public class MucManager : StreamInteractionModule, Object {
|
|||
}
|
||||
mucs_todo[account].add(jid.with_resource(nick_));
|
||||
|
||||
Muc.JoinResult? res = yield stream.get_module(Xep.Muc.Module.IDENTITY).enter(stream, jid.bare_jid, nick_, password, history_since, receive_history, null);
|
||||
var? module = stream.get_module(Xep.Muc.Module.IDENTITY);
|
||||
if (module == null) {
|
||||
var res = new Muc.JoinResult();
|
||||
res.muc_error = null;
|
||||
res.nick = null;
|
||||
res.stanza_error = "unexpected null module";
|
||||
return res;
|
||||
}
|
||||
|
||||
Muc.JoinResult? res = yield module.enter(stream, jid.bare_jid, nick_,
|
||||
password, history_since, receive_history, null);
|
||||
|
||||
mucs_joining[account].remove(jid);
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@ public const string NS_URI = "urn:xmpp:sm:3";
|
|||
public class Module : XmppStreamNegotiationModule, WriteNodeFunc {
|
||||
public static ModuleIdentity<Module> IDENTITY = new ModuleIdentity<Module>(NS_URI, "0198_stream_management");
|
||||
|
||||
public signal void got_session_id(string session_id);
|
||||
|
||||
public int h_inbound = 0;
|
||||
public int h_outbound = 0;
|
||||
|
||||
|
@ -127,11 +129,12 @@ public class Module : XmppStreamNegotiationModule, WriteNodeFunc {
|
|||
h_inbound++;
|
||||
}
|
||||
|
||||
private void check_resume(XmppStream stream) {
|
||||
public void check_resume(XmppStream stream) {
|
||||
if (stream_has_sm_feature(stream) && session_id != null) {
|
||||
StanzaNode node = new StanzaNode.build("resume", NS_URI).add_self_xmlns()
|
||||
.put_attribute("h", h_inbound.to_string())
|
||||
.put_attribute("previd", session_id);
|
||||
session_id = null;
|
||||
write_node.begin(stream, node);
|
||||
stream.add_flag(new Flag());
|
||||
}
|
||||
|
@ -158,6 +161,8 @@ public class Module : XmppStreamNegotiationModule, WriteNodeFunc {
|
|||
if (node.name == "enabled") {
|
||||
h_inbound = 0;
|
||||
session_id = node.get_attribute("id", NS_URI);
|
||||
print(@"this=%p, new session_id=$(session_id)\n", this);
|
||||
got_session_id(session_id);
|
||||
flags = stream.flags;
|
||||
((IoXmppStream)stream).write_obj = this;
|
||||
} else if (node.name == "resumed") {
|
||||
|
@ -219,6 +224,13 @@ public class Module : XmppStreamNegotiationModule, WriteNodeFunc {
|
|||
}
|
||||
|
||||
private bool stream_has_sm_feature(XmppStream stream) {
|
||||
print("stream=%p\n", stream);
|
||||
if (session_id != null) {
|
||||
print(@"session_id=$(session_id)\n");
|
||||
}
|
||||
if (stream.features.get_subnode("sm", NS_URI) != null) {
|
||||
print(@"stream.features.get_subnode=$(stream.features.get_subnode("sm", NS_URI))\n");
|
||||
}
|
||||
return stream.features.get_subnode("sm", NS_URI) != null;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue