/// <summary> /// Главниот дел - хендлерот за пакети /// </summary> /// <param name="packet"></param> public void notify(Packet packet) { String type = packet.Type; Packet query = packet.getFirstChild("query"); username = query.getChildValue("username"); iq.setID(packet.getID()); iq.Session = packet.Session; iq.getChildren().Clear(); iq.Type = "result"; reply = new Packet("query"); reply.setAttribute("xmlns", "jabber:iq:auth"); reply.Parent = iq; user = userIndex.getUser(username); if (user == null) { sendErrorPacket(404, "User not found"); return; } if (userIndex.sessionIndex.ContainsValue(user) == true) { sendErrorPacket(404, "User already Logged In"); return; } if (type.Equals("get")) { sendGetPacket(); return; } else if (type.Equals("set")) { session = packet.Session; if (session.Status != Session.SessionStatus.streaming) { sendErrorPacket(400, "Server name does not match"); return; } resource = query.getChildValue("resource"); if (resource == null) { sendErrorPacket(404, "You must send resource"); return; } handleSetPacket(query); return; } }
}//update roster public void informSubscriber() { //needs to be checked! if ((Server.JabberServer.RosterHashtable[this.user] as UserRoster) != null) { foreach (object obj in (Server.JabberServer.RosterHashtable[this.user] as UserRoster).subscribers.Keys) { Subscriber sub = (Server.JabberServer.RosterHashtable[this.user] as UserRoster).subscribers[obj] as Subscriber; if (sub.subscription.Equals("from") || sub.subscription.Equals("both"))//inform sender of his subscribers status! { JabberID myid = new JabberID(obj.ToString());//other's subscribers id if (myid.Domain.Equals(Server.JabberServer.server_name))//if from this server { //new code! if (Server.JabberServer.getUserIndex().getUser(myid.User).getSessions().Values==null) { // if Server.JabberServer.getUserIndex().getUser(myid.User).getSessions() //user is offline Packet presencePacket = new Packet("presence"); presencePacket.From = myid.ToString(); presencePacket.To = new JabberID(this.user + "@" + Server.JabberServer.server_name).ToString(); presencePacket.setAttribute("type", "unavailable"); MessageHandler.deliverPacket(presencePacket); }// if (Server.JabberServer.getUserIndex().getUser(myid.User).getSessions().Values!=null) else { foreach (Object obj2 in (Server.JabberServer.getUserIndex().getUser(myid.User).getSessions().Values)) {//for each active session Session sess = obj2 as Session; Packet presencePacket = new Packet("presence"); presencePacket.From = myid.ToString(); presencePacket.To = new JabberID(this.user + "@" + Server.JabberServer.server_name).ToString(); if (sess.getPresence().isAvailible()) { presencePacket.setAttribute("type", "available"); if(sess.getPresence().getShow()!=null) presencePacket.Children.Add(new Packet("show",sess.getPresence().getShow())); if(sess.getPresence().getStatus()!=null) presencePacket.Children.Add(new Packet("status",sess.getPresence().getStatus())); if (sess.getPresence().getPriority() != null) presencePacket.Children.Add(new Packet("priority", sess.getPresence().getPriority())); //other info may be added! } else presencePacket.setAttribute("type", "unavailable"); MessageHandler.deliverPacket(presencePacket); }//for each active session } }// if(myid.Domain.Equals(Server.JabberServer.server_name)) else { //generate probe for S2S communication!@TODO } }//if (sub.subscription.Equals("from") || sub.subscription.Equals("both")) }//foreach (object obj in (Server.JabberServer.RosterHashtable[this.user] as UserRoster).subscribers.Keys) }//if ((Server.JabberServer.RosterHashtable[this.user] as UserRoster) != null) }
}//Update subscribers public Packet getPacket() { Packet packet = new Packet("query"); packet.setAttribute("xmlns", "jabber:iq:roster"); //works, checked!: if ((Server.JabberServer.RosterHashtable[this.user] as UserRoster) != null) { foreach (object obj in (Server.JabberServer.RosterHashtable[this.user] as UserRoster).items.Values) { ((Packet)obj).Parent = packet; } return packet; } else return packet; }//getPacket
public void updatePresence(Packet presence) { String type = presence.Type; Session session = presence.Session; Presence sessionPresence = session.getPresence(); String recipient = presence.To; JabberID recipientID; Boolean isUserSent;//it is not used yet, may be used in S2S comunication //packet filling begins if (recipient == null) { //directed to server //server name recipientID = new JabberID(Server.JabberServer.server_name); isUserSent = true; } else { recipientID = new JabberID(recipient); if (user.Equals(recipientID.User)) { isUserSent = false; } else { isUserSent = true; } } String sender = presence.From; JabberID SenderID; if (sender == null) { SenderID = session.JID; } else { SenderID = new JabberID(sender); } //added by marko presence.From = SenderID.User + "@" + SenderID.Domain; //original line: //String subscriber = isUserSent ? recipientID.ToString() : SenderID.ToString(); String subscriber = recipientID.ToString(); if (type == null) { type = "available"; } //packet filling ends //packet routing begins if (type.Equals("available") || type.Equals("unavailable")) { //user-managed presence updates are delivered untouched if (!recipientID.ToString().Equals(Server.JabberServer.server_name)) { //may need some work; MessageHandler.deliverPacket(presence); return; } //Server-managed presence updates are forwarded only to subscribers //update the session's presence status sessionPresence.Availible = type.Equals("available"); sessionPresence.Show = presence.getChildValue("show"); sessionPresence.Status = presence.getChildValue("status"); String priority = presence.getChildValue("priority"); sessionPresence.Priority = priority; if (priority != null) { //some code to set the priority of the session try { session.setPriority(int.Parse(priority)); } catch (Exception ex) { JabberServer.output.WriteLine("Error in incoming priority, setting priority to default: 1"); session.setPriority(0); } } //deliver to all users presence subscribers updateSubscribers(presence); informSubscriber(); return; } if (type.Equals("probe")) { //needed for server to server communication!!!! JabberServer.output.WriteLine("Roster: We don't handle probes yet " + presence.ToString()); return; } //Marko believes it is checked for exceptions //Subscriber sendersSubscriberItem = (Subscriber)subscribers[subscriber]; Subscriber sendersSubscriberItem = new Subscriber(); Hashtable Rosters = JabberServer.RosterHashtable;//get reference to rosters //prepare sender's roster UserRoster senderRoster = Rosters[this.user] as UserRoster;//getting senders roster if (senderRoster == null) { senderRoster = new UserRoster(); senderRoster.user = this.user; } if (!Rosters.ContainsKey(this.user)) { Rosters.Add(this.user, senderRoster); } //prepare recipients roster UserRoster recipientRoster = Rosters[recipientID.User] as UserRoster;//getting recipients roster if (recipientRoster == null) { recipientRoster = new UserRoster(); recipientRoster.user = recipientID.User; } if (!Rosters.ContainsKey(recipientID.User)) { Rosters.Add(recipientID.User, recipientRoster); } sendersSubscriberItem = senderRoster.subscribers[subscriber] as Subscriber;//extra if (sendersSubscriberItem == null) { //create subscription item sendersSubscriberItem = new Subscriber(); sendersSubscriberItem.subscription = "none"; senderRoster.subscribers.Add(recipient, sendersSubscriberItem); Packet itempacket = new Packet("item"); itempacket.setAttribute("jid", subscriber); senderRoster.items.Add(subscriber, itempacket); } //begin subscription managment if (type.Equals("subscribe")) { sendersSubscriberItem.ask = type;//set up subscription status } else if (type.Equals("subscribed"))//if subscription accepted { sendersSubscriberItem.ask = null; if (sendersSubscriberItem.subscription.Equals("from")) { sendersSubscriberItem.subscription = "both"; } else if (sendersSubscriberItem.subscription.Equals("none")) { sendersSubscriberItem.subscription = "to"; } } else if (type.Equals("unsubscribed")) {//sender does not want to give presence updates to recipient sendersSubscriberItem.ask = null; if (sendersSubscriberItem.subscription.Equals("to")) { sendersSubscriberItem.subscription = "none"; } else if (sendersSubscriberItem.subscription.Equals("both")) { sendersSubscriberItem.subscription = "from"; } //notify recipient of sender's unavailble status: Packet unavailiblePacket = new Packet("presence"); unavailiblePacket.setFrom(presence.From); unavailiblePacket.To = presence.To; unavailiblePacket.setAttribute("type", "unavailable"); MessageHandler.deliverPacket(unavailiblePacket); } else if (type.Equals("unsubscribe")) {//sender no longer interested in recieving presence updates from recipient sendersSubscriberItem.ask = null; if (sendersSubscriberItem.subscription.Equals("both")) { sendersSubscriberItem.subscription = "to"; } else if (sendersSubscriberItem.subscription.Equals("from")) { sendersSubscriberItem.subscription = "none"; } } //update the corresponding changes in <items> table in sender's record used for delivery Packet item = (Packet)senderRoster.items[subscriber]; if (item != null) { item.setAttribute("subscription", sendersSubscriberItem.subscription); item.setAttribute("ask", sendersSubscriberItem.ask); Packet iq = new Packet("iq"); iq.Type = "set"; Packet query = new Packet("query"); query.setAttribute("xmlns", "jabber:iq:roster"); query.setParent(iq); item.setParent(query); iq.To = this.user + "@" + Server.JabberServer.server_name; //Forward the subscription packet to recipient MessageHandler.deliverPacketToAll(user, iq);//may need some correction! } //processing of recipients roster begins if (sendersSubscriberItem.ask == null) { //the recipient user rosters update! Subscriber recipientsSubscriberItem = recipientRoster.subscribers[user + "@" + JabberServer.server_name] as Subscriber;//extra if (recipientsSubscriberItem == null) { //create subscription item recipientsSubscriberItem = new Subscriber(); recipientsSubscriberItem.subscription = "none"; recipientRoster.subscribers.Add(user + "@" + JabberServer.server_name, recipientsSubscriberItem); } //if type is subscribe, changes in this roster are not needed!!! if (type.Equals("subscribed"))//if subscription accepted { recipientsSubscriberItem.ask = null; if (recipientsSubscriberItem.subscription.Equals("none")) { recipientsSubscriberItem.subscription = "from"; } else if (recipientsSubscriberItem.subscription.Equals("to")) { recipientsSubscriberItem.subscription = "both"; } } else if (type.Equals("unsubscribed")) {//sender no longer interested in giving presence updates to recipient recipientsSubscriberItem.ask = null; if (recipientsSubscriberItem.subscription.Equals("both")) { recipientsSubscriberItem.subscription = "to"; } else if (recipientsSubscriberItem.subscription.Equals("from")) { recipientsSubscriberItem.subscription = "none"; } } else if (type.Equals("unsubscribe")) {//sender no longer interested in recieving presence updates from recipient recipientsSubscriberItem.ask = null; if (recipientsSubscriberItem.subscription.Equals("to")) { recipientsSubscriberItem.subscription = "none"; } else if (recipientsSubscriberItem.subscription.Equals("both")) { recipientsSubscriberItem.subscription = "from"; } //notify sender of unavailble status: Packet unavailiblePacket = new Packet("presence"); unavailiblePacket.setFrom(presence.To); unavailiblePacket.To = presence.From; unavailiblePacket.setAttribute("type", "unavailable"); MessageHandler.deliverPacket(unavailiblePacket); } //update the corresponding changes in <items> table in sender's record used for delivery Packet item2 = (Packet)recipientRoster.items[user + "@" + JabberServer.server_name]; if (item2 != null) { item2.setAttribute("subscription", recipientsSubscriberItem.subscription); item2.setAttribute("ask", recipientsSubscriberItem.ask); Packet iq = new Packet("iq"); iq.Type = "set"; Packet query = new Packet("query"); query.setAttribute("xmlns", "jabber:iq:roster"); query.setParent(iq); item2.setParent(query); iq.To = recipientID.User + "@" + recipientID.Domain; //Forward the subscription packet to recipient MessageHandler.deliverPacketToAll(user, iq);//may need some correction! } } MessageHandler.deliverPacket(presence); }//UpdatePresense
public void process(Session session) { //Assembly assem = Assembly.LoadFrom(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + @"\SaxExpat.dll"); //IXmlReader reader = SaxReaderFactory.CreateReader(assem, null); //reader.ContentHandler = this; this.session = session; //reader.Parse(new ReaderInputSource(session.getReader())); XmlReader reader = XmlReader.Create(session.Reader); JabberServer.output.WriteLine("JIH:server version"); reader.MoveToContent(); try { do { switch (reader.Depth) { case 0: switch (reader.NodeType) { case XmlNodeType.Element: if (reader.Name == "stream:stream") { Dictionary<String, String> atts = getAttributes(reader); Packet openPacket = new Packet(null, reader.Name, reader.NamespaceURI, atts); openPacket.Session = (session); String from = atts["from"]; session.JID = (new JabberID(from)); packetQ.enqueue(openPacket); } else { throw new XmlException("Root node must be <stream:stream>"); } break; case XmlNodeType.EndElement: Packet closePacket = new Packet("/stream:stream"); closePacket.Session = (session); packetQ.enqueue(closePacket); break; } break; case 1: switch (reader.NodeType) { case XmlNodeType.Element: Dictionary<String, String> atts = getAttributes(reader); packet = new Packet(null, reader.Name, reader.NamespaceURI, atts); packet.Session = (session); if (reader.IsEmptyElement) goto case XmlNodeType.EndElement; break; case XmlNodeType.EndElement: packetQ.enqueue(packet); break; } break; default: switch (reader.NodeType) { case XmlNodeType.Element: Dictionary<String, String> atts = getAttributes(reader); Packet child = new Packet(packet, reader.Name, reader.NamespaceURI, atts); packet = child; if (reader.IsEmptyElement) goto case XmlNodeType.EndElement; break; case XmlNodeType.EndElement: packet = packet.Parent; break; case XmlNodeType.Text: packet.Children.Add(reader.Value); break; } break; } } while (reader.Read()); } catch (Exception ex) { //JabberServer.output.WriteLine(ex.ToString()); // Bilokakov problem so xml stream-ot // io-exception, invalid xml, zatvoren socket i sl. // treba da se napravi clean-up : zatvori stream </stream:stream>, zatvori socket, trgni Session object i sl. // Ne sekogas znaci greska : posle </stream:stream> se zatvara socket-ot i ne treba da se pravi nisto UserIndex userIndex = JabberServer.getUserIndex(); if (!userIndex.containsSession(session)) { return; } //clean-up code (copied from CloseStreamHandler) try { // Log.trace("Closing session"); //Session session = packet.Session; //session.Writer.Write("</stream:stream> "); //session.Writer.Flush(); //notify other subscribers that user is unavailble //by Marko //begin JabberID userid = session.getJID(); Packet unavailiblePacket = new Packet("presence"); unavailiblePacket.setFrom(userid.ToString()); unavailiblePacket.setAttribute("type", "unavailable"); userIndex.getUser(userid.User).getRoster().updateSubscribers(unavailiblePacket); //it is not tested, but it should work //end //send groupchat presence unavailable & remove from groups String jid = userid.ToString(); Packet presence = new Packet("presence"); presence.Type = "unavailable"; foreach (KeyValuePair<String, GroupChatManager.Group> kvp in GroupChatManager.Manager.groups) { GroupChatManager.Group group = kvp.Value; try { String nick = group.jid2nick[jid]; // test whether the user is in the group presence.From = group.JabberID + "/" + nick; GroupChatManager.Manager.removeUser(group, jid); // first remove then deliver so that the packet does not come back GroupChatManager.Manager.deliverToGroup(group, presence); } catch (Exception e) { } } // end groupchar clean-up //session.Socket.Close(); userIndex.removeSession(session); // Log.trace("Closed session"); } catch (Exception e) { // Log.error("CloseStreamHandler: ",ex); userIndex.removeSession(packet.Session); // Log.trace("Exception closed session"); } } }
public void notify(Packet packet) { try { // Log.trace("Closing session"); Session session = packet.Session; session.Writer.Write("</stream:stream> "); session.Writer.Flush(); //notify other subscribers that user is unavailble //by Marko //begin JabberID userid = session.getJID(); Packet unavailiblePacket = new Packet("presence"); unavailiblePacket.setFrom(userid.ToString()); unavailiblePacket.setAttribute("type", "unavailable"); userIndex.getUser(userid.User).getRoster().updateSubscribers(unavailiblePacket); //it is not tested, but it should work //end //send groupchat presence unavailable & remove from groups String jid = userid.ToString(); Packet presence = new Packet("presence"); presence.Type = "unavailable"; foreach (KeyValuePair<String, GroupChatManager.Group> kvp in GroupChatManager.Manager.groups) { GroupChatManager.Group group = kvp.Value; try { String nick = group.jid2nick[jid]; // test whether the user is in the group presence.From = group.JabberID + "/" + nick; GroupChatManager.Manager.removeUser(group, jid); // first remove then deliver so that the packet does not come back GroupChatManager.Manager.deliverToGroup(group, presence); } catch (Exception ex) { } } // end groupchar clean-up //session.Socket.Close(); userIndex.removeSession(session); // Log.trace("Closed session"); } catch (Exception ex) { JabberServer.output.WriteLine(ex.ToString()); // Log.error("CloseStreamHandler: ",ex); // packet.Session.Socket.Close(); // userIndex.removeSession(packet.Session); // Log.trace("Exception closed session"); } finally { packet.Session.Socket.Close(); } }
//end added by marko public void sendRosterSet(String jid, String name, string group) { //hashtable type may be changed Packet packet = new Packet("iq"); packet.Type = "set"; packet.ID = "roster_set"; Packet query = new Packet("query"); query.setAttribute("xmlns", "jabber:iq:roster"); query.setParent(packet); Packet item = new Packet("item"); item.setAttribute("jid", jid); if(name != null) { item.setAttribute("name", name); } item.setParent(query); //code to form the packets if(group != null) { new Packet("group", group).setParent(item); } session.Writer.Write(packet.ToString()); session.Writer.Flush(); }
public void sendRosterSet(String jid, String name, Hashtable groups)//hashtable type may be changed { Packet packet = new Packet("iq"); packet.Type = "set"; packet.ID = "roster_set"; Packet query = new Packet("query"); query.setAttribute("xmlns", "jabber:iq:roster"); query.setParent(packet); Packet item = new Packet("item"); item.setAttribute("jid", jid); item.setAttribute("name", name); item.setParent(query); //code to form the packets foreach (object key in groups.Keys) { new Packet("group", groups[key].ToString()).setParent(item); } session.Writer.Write(packet.ToString()); session.Writer.Flush(); }
public void sendRosterRemove(String jid) { Packet packet = new Packet("iq"); packet.Type = "set"; packet.setID("roster_remove"); Packet query = new Packet("query"); query.setAttribute("xmlns", "jabber:iq:roster"); query.Parent = packet; Packet item = new Packet("item"); item.setAttribute("jid", jid); item.setAttribute("subscription", "remove"); item.Parent = query; session.Writer.Write(packet.ToString()); session.Writer.Flush(); }
//Крај додадено //added by marko //roster/presence management public void sendRosterGet() { Packet packet = new Packet("iq"); packet.Type = "get"; packet.ID = "roster_get_id"; Packet query = new Packet("query"); query.setAttribute("xmlns", "jabber:iq:roster"); query.setParent(packet); session.Writer.Write(packet.ToString()); session.Writer.Flush(); }