private void SendOfflineMessages(XmppSession session) { if (!session.IsSignalRFake) { var domain = session.Stream.Domain; foreach (var m in offlineStore.GetOfflineMessages(session.Jid)) { var delay = new Element("delay"); delay.SetNamespace("urn:xmpp:delay"); delay.SetAttribute("From", domain); delay.SetAttribute("stamp", Time.Date(m.XDelay.Stamp)); delay.Value = "Offline Storage"; m.AddChild(delay); m.XDelay.From = new Jid(domain); m.XDelay.Value = "Offline Storage"; sender.SendTo(session, m); } if (session.Jid.Resource != "TMTalk") { offlineStore.RemoveAllOfflineMessages(session.Jid); } } }
private void IQLost(object sender, TimeoutEventArgs e) { var iq = (IQ)e.Data; var session = sessionManager.GetSession(iq.From); if (session != null) { // iChat bug if (iq.Id == null || iq.Id.IndexOf("ichat", StringComparison.OrdinalIgnoreCase) < 0) { xmppSender.SendTo(session, XmppStanzaError.ToServiceUnavailable(iq)); } else { xmppSender.SendTo(session, ToResult(iq)); } } }
private void IQLost(object sender, TimeoutEventArgs e) { var iq = (IQ)e.Data; var session = sessionManager.GetSession(iq.From); if (session != null) { xmppSender.SendTo(session, XmppStanzaError.ToServiceUnavailable(iq)); } }
public void ProcessStreamElement(Node node, XmppStream stream) { if (node == null) { throw new ArgumentNullException("node"); } if (stream == null) { throw new ArgumentNullException("stream"); } try { var address = new Jid(stream.Domain); foreach (var handler in HandlerStorage.GetStreamHandlers(address, node.GetType())) { handler.ElementHandle(stream, (Element)node.Clone(), context); } if (node is Stanza) { var stanza = (Stanza)node; if (!validator.ValidateStanza(stanza, stream, context)) { return; } if (stanza.HasTo) { address = stanza.To; } var handlres = HandlerStorage.GetStanzaHandlers(address, GetStanzaType(stanza)); if (handlres.Count == 0) { if (stanza is IQ) { var iq = (IQ)stanza; if ((iq.Type == IqType.error || iq.Type == IqType.result) && iq.HasTo && iq.To.HasUser) { //result and error retranslate to user var session = context.SessionManager.GetSession(iq.To); if (session != null) { sender.SendTo(session, iq); return; } } //result and error ignored by server } sender.SendTo(stream, XmppStanzaError.ToServiceUnavailable(stanza)); log.DebugFormat("Stanza handler not found for address '{0}'", address); return; } bool iqHandled = true; Stopwatch stopwatch = null; foreach (var handler in handlres) { if (log.IsDebugEnabled) { stopwatch = Stopwatch.StartNew(); } if (stanza is IQ) { var answer = handler.HandleIQ(stream, (IQ)stanza.Clone(), context); if (answer != null) { sender.SendTo(stream, answer); iqHandled = answer.Id == stanza.Id; } } else if (stanza is Message) { handler.HandleMessage(stream, (Message)stanza.Clone(), context); } else if (stanza is Presence) { handler.HandlePresence(stream, (Presence)stanza.Clone(), context); } else { sender.SendTo(stream, XmppStanzaError.ToNotAcceptable(stanza)); return; } if (log.IsDebugEnabled) { stopwatch.Stop(); log.DebugFormat("Process stanza handler '{1}' on address '{0}', time: {2}ms", address, handler.GetType().FullName, stopwatch.Elapsed.TotalMilliseconds); } } if (!iqHandled) { sender.SendTo(stream, XmppStanzaError.ToServiceUnavailable(stanza)); return; } } } catch (Exception ex) { ProcessException(ex, node, stream); } }
public void Send(Stanza stanza) { stanza.To = RealJid; sender.SendTo(Stream, stanza); }
private void HandlePresence(Presence presence, XmppSession session) { var toRosterItem = GetUserRosterItem(presence.From, presence.To); var fromRosterItem = GetUserRosterItem(presence.To, presence.From); var stateOut = GetState(fromRosterItem, toRosterItem); var stateIn = GetState(toRosterItem, fromRosterItem); bool bRoute = false; bool bAutoReply = false; bool bMutualCreating = (fromRosterItem.Subscribtion == SubscriptionType.to && toRosterItem.Subscribtion == SubscriptionType.from) || (fromRosterItem.Subscribtion == SubscriptionType.from && toRosterItem.Subscribtion == SubscriptionType.to); var newType = presence.Type; if (newType == PresenceType.subscribe) { if (bMutualCreating) { if (toRosterItem.Subscribtion == SubscriptionType.from && toRosterItem.Ask == AskType.NONE) { //Push roster with ASK=subscribe toRosterItem.Ask = AskType.subscribe; UpdateItems(presence, ref fromRosterItem, ref toRosterItem); //Push sender.Broadcast( sessionManager.GetBareJidSessions(presence.From), toRosterItem.GetRosterIq(presence.From) ); //Forward presence.To = new Jid(presence.To.Bare); bool sended = sender.Broadcast(sessionManager.GetBareJidSessions(presence.To), presence); if (!sended) { StoreOffline(presence); } } } else { //it's inbound for user 'to' ChangeInboundPresence(stateIn, toRosterItem, fromRosterItem, newType, out bRoute, out bAutoReply); if (bAutoReply) { //Reply with 'subscribed' var autoPresence = new Presence(); autoPresence.To = presence.From; autoPresence.From = presence.To; autoPresence.Type = PresenceType.subscribed; sender.Broadcast(sessionManager.GetBareJidSessions(autoPresence.To), autoPresence); } else { if (bRoute) { //Send to 'to' user presence.To = new Jid(presence.To.Bare); bool sended = sender.Broadcast(sessionManager.GetBareJidSessions(presence.To), presence); if (!sended) { StoreOffline(presence); } //State is changed init roster push UpdateItems(presence, ref fromRosterItem, ref toRosterItem); sender.Broadcast( sessionManager.GetBareJidSessions(presence.From), toRosterItem.GetRosterIq(presence.From) ); //Send result stanza sender.SendTo(session, new IQ(IqType.result)); } } } } else if (newType == PresenceType.subscribed) { if (bMutualCreating) { if (fromRosterItem.Subscribtion == SubscriptionType.from && fromRosterItem.Ask == AskType.subscribe) { //Send roster to contact with both to 'from' //Create both subscription //Send subscribed back toRosterItem.Subscribtion = SubscriptionType.both; toRosterItem.Ask = AskType.NONE; UpdateItems(presence, ref fromRosterItem, ref toRosterItem); sender.Broadcast( sessionManager.GetBareJidSessions(presence.From), toRosterItem.GetRosterIq(presence.From) ); sender.SendTo(session, new IQ(IqType.result)); //fwd presence.To = new Jid(presence.To.Bare); if (!sender.Broadcast(sessionManager.GetBareJidSessions(presence.To), presence)) { StoreOffline(presence); } //Send contact with both fromRosterItem.Subscribtion = SubscriptionType.both; fromRosterItem.Ask = AskType.NONE; UpdateItems(presence, ref fromRosterItem, ref toRosterItem); sender.Broadcast( sessionManager.GetBareJidSessions(presence.To), fromRosterItem.GetRosterIq(presence.To) ); //Send to session presence if (session.Presence != null) { sender.Broadcast(sessionManager.GetBareJidSessions(presence.To), session.Presence); } } } else { //It's outbound for user 'from' ChangeOutboundPresence(stateOut, toRosterItem, fromRosterItem, newType, out bRoute); //Roster oush for 'from' if (bRoute) { //State is changed init roster push UpdateItems(presence, ref fromRosterItem, ref toRosterItem); sender.Broadcast( sessionManager.GetBareJidSessions(presence.From), toRosterItem.GetRosterIq(presence.From) ); //Send result stanza sender.SendTo(session, new IQ(IqType.result)); //dont send } //It's inbound for user 'to' if ((fromRosterItem.Subscribtion == SubscriptionType.none || fromRosterItem.Subscribtion == SubscriptionType.from) && fromRosterItem.Ask == AskType.subscribe) { ChangeInboundPresence(stateIn, fromRosterItem, toRosterItem, newType, out bRoute, out bAutoReply); if (bRoute) { presence.To = new Jid(presence.To.Bare); if (sender.Broadcast(sessionManager.GetBareJidSessions(presence.To), presence)) { StoreOffline(presence); } else { if (session.Presence != null) { sender.Broadcast(sessionManager.GetBareJidSessions(presence.To), session.Presence); } } //State is changed init roster push UpdateItems(presence, ref fromRosterItem, ref toRosterItem); sender.Broadcast( sessionManager.GetBareJidSessions(presence.To), fromRosterItem.GetRosterIq(presence.To)); } } } } else if (newType == PresenceType.unsubscribe) { //Get to roster //it's inbound for user 'to' ChangeInboundPresence(stateIn, toRosterItem, fromRosterItem, newType, out bRoute, out bAutoReply); if (bAutoReply) { //Reply with 'subscribed' Presence autoPresence = new Presence(); autoPresence.To = presence.From; autoPresence.From = presence.To; autoPresence.Type = PresenceType.unsubscribed; sender.Broadcast(sessionManager.GetBareJidSessions(autoPresence.To), autoPresence); //Route presence.To = new Jid(presence.To.Bare); if (!sender.Broadcast(sessionManager.GetBareJidSessions(presence.To), presence)) { StoreOffline(presence); } } } else if (newType == PresenceType.unsubscribed) { //It's outbound for user 'from' ChangeOutboundPresence(stateOut, toRosterItem, fromRosterItem, newType, out bRoute); //Roster oush for 'from' if (bRoute) { //State is changed init roster push UpdateItems(presence, ref fromRosterItem, ref toRosterItem); sender.Broadcast( sessionManager.GetBareJidSessions(presence.From), toRosterItem.GetRosterIq(presence.From)); //Send result stanza sender.SendTo(session, new IQ(IqType.result)); //dont send } ChangeInboundPresence(stateIn, fromRosterItem, toRosterItem, newType, out bRoute, out bAutoReply); if (bRoute) { presence.To = new Jid(presence.To.Bare); if (!sender.Broadcast(sessionManager.GetBareJidSessions(presence.To), presence)) { StoreOffline(presence); } else { sender.Broadcast( sessionManager.GetBareJidSessions(presence.To), new Presence() { Type = PresenceType.unavailable, From = presence.From }); } //State is changed init roster push UpdateItems(presence, ref fromRosterItem, ref toRosterItem); sender.Broadcast( sessionManager.GetBareJidSessions(presence.To), fromRosterItem.GetRosterIq(presence.To)); } } UpdateItems(presence, ref fromRosterItem, ref toRosterItem); }