Myicq-1.0A1 server code analysis (1)
Solarsoft
Myicq code has been published for a while. I heard that Zhang Yong has no longer disclosed server-side code, not feeling unfortunately, I have been a time to read his work. Today, I will give it to my opinion.
I now talk about his server-side code from the overall architecture, and the server code can be divided into database, UPD service, server group, and plug-ins.
I have some discussion on the implementation of UPD services here.
First, the data buffer package management
First define abstract class Outpacket and Inpacket, the code is as follows:
Class Outpacket {
PUBLIC:
Virtual Outpacket & Operator << (uint8 b) = 0;
Virtual Outpacket & Operator << (uint16 w) = 0;
Virtual Outpacket & Operator << (uint32 dw) = 0;
Virtual Outpacket & Operator << (ICQ_STR & STR) = 0;
}
Class inpacket {
PUBLIC:
Virtual Incacket & Operator >> (UINT8 & B) = 0;
Virtual Incacket & Operator >> (UINT16 & W) = 0;
Virtual Incacket & Operator >> (UINT32 & DW) = 0;
Virtual Incacket & Operator >> (ICQ_STR & STR) = 0;
}
In the implementation of its partial ICQOTPACKET and ICQINPACKET, and define the data buffer uint8 data [udp_packet_size], the size is 1024, mainly to process the input and output of the data.
Then derive its UDPOUTPACKET and UDPINPACKET, at which point DES data encryption and decryption, and add the data head, defined as follows:
Struct UDP_CLI_HDR {
UINT16 VER;
Uint32 reserved;
UINT32 UIN;
UINT32 SID;
UINT16 CMD;
UINT16 SEQ;
UINT16 CC; // Check Code
}
Struct udp_srv_hdr {
UINT16 VER;
Uint32 reserved;
UINT32 UIN;
UINT32 SID;
UINT16 CMD;
UINT16 SEQ;
UINT16 ACKSEQ;
}
At this time, the package class of the buffer has ended.
Second, the writing of Socket service code
First define 2 classes REFOBJECT and SESSION, where RefObject is a count class, the two generations are as follows:
Class RefObject {
PUBLIC:
REFOBJECT () {
REFCOUNT = 1;
}
Int addref () {
Return refcount;
}
Int release () {
Register int Ret = --Refcount;
IF (! RET)
DELETE THIS;
Return Ret;
}
protected:
Virtual ~ refObject () {}
Int refcount;
}
Class session {
PUBLIC:
UINT32 UIN;
Uint32 status;
UINT32 IP; uint16 msgport;
UINT32 Realip;
}
Now let's take a look at the definition of the UDP service class.
Class udpsession: public refobject, public session {
PUBLIC:
UDPSession (udpinpacket & in, uint32 ip, uint16 port);
~ Udpsession ();
UDPOUTPACKET * CREATEPACKET (UINT16 CMD, UINT16 ACKSEQ = 0);
Void SendPacket (udpoutpacket * p);
Void Sendonline (session * s, icq_str & domain);
Void Sendoffline (uint32 uin, icq_str & domain);
Void SendStatusChanged (session * s, icq_str & domain);
Void SendMessage (Uint8 Type, QID & SRC, UINT32 WHEN, ICQ_STR & TEX);
Void sendgrouptypes ();
Void UpdateContactReply (uint16 SEQ, UINT8 * DATA, INT N, Server * Server = NULL);
Void Searchrandomreply (uint16 seq, uint8 * data, int N);
Void searchuinReply (uint16 seq, uint8 * data, int N);
Void dead ();
Void logout ();
Void onlineNotify ();
Void offlinenotify ();
Void StatusNotify (uint32 newstatus);
Static bool init ();
Static void destroy ();
Static bool onreceive ();
Static void checksendqueue ();
Static void checkkeepalive ();
Static Void SendMessage (Uint8 Type, QID & DST, QID & SRC, UINT32 WHEN, ICQ_STR & TEX);
Static Void AddFriend (Uint16 SEQ, QID & DST, UINT32 SRC, Server * Server = null);
Static Void AddFriendAuth (Uint16 SEQ, QID & DST, UINT32 SRC, Server * Server, Uint8 Auth, Bool SendAuthmsg = true);
Static Void UpdateContact (uint16 SEQ, UINT32 DST, UINT32 SRC, Server * Server = NULL);
Static void searchuin (uint16 SEQ, UINT32 DST, UINT32 SRC, Server * Server = NULL);
Uint8 auth;
Uint8 face;
Char Nickname [MAX_NICK 1];
Char province [max_Province 1];
UINT16 TCPVER;
UINT16 Port;
UINT32 OLDMSGID, LASTMSGID;
Char Subkey [128];
Listhead uinitem;
Listhead ipportItem;
Listhead ListItem;
Static int suck;
STATIC uint32 sessioncount;
Private:
Void CreatePacket (uDpoutpacket, uint16 cmd, uint16 seq, uint16 Ackseq);
Void Senddirect (udpoutpacket * p);
Void SendackPacket (uint16 seq);
Bool setWindow;
Void Notify (DB_Callback CB1, DB_CALLBACK CB2);
Void Onack (UINT16 SEQ);
Void onkeepalive (udpinpacket & in);
Void Onnewuin (udpinpacket & in);
Void ONGETCONTACTLIST (UDPinPacket & IN);
Void ONGETREMOTECONTACTLIST (UDPINPACKET & IN);
Void Onlogin (udpinpanet & in);
Void Onlogout (udpinpanet & in);
Void onchangeestatus (udpinpacket & in);
Void OnUpdateContact (udpinpacket & in);
Void OnModifyUser (udpinpacket & in);
Void onupdateuser (udpinpanet & in);
Void OnsendMessage (udpinpacket & in);
Void OnSearchrandom (udpinpanet & in);
Void OnSearchCustom (udpinpacket & in);
Void OnaddFriend (udpinpacket & in);
Void OnDelfRiend (udpinpacket & in);
Void Onsendbcmsg (UDPinPacket & IN);
Void ONGETSERVERLIST (UDPinPacket & IN);
Void ONGETGROUPLIST (UDPinPacket & IN);
Void OnSearchGroup (udpinpacket & in);
Void oncreategroup (udpinpacket & in);
Void Onentergroup (udpinpacket & in);
Void Onexitgroup (udpinpacket & in);
Void ONGROUPSTART (UDPINPACKET & IN);
Void ONGROUPMESSAGE (UDPINPACKET & IN);
Void ONGROUPCMD (UDPinPacket & IN);
Bool OnPacketReceived (udpinpacket & in);
UINT16 UDPVER;
UINT32 SID;
UINT16 SendSeq;
UINT16 Recvseq;
Uint32 window;
TIME_T Expire;
Uint8 isdead: 1;
Icqgroup * group;
Listhead sendqueue;
Declare_slab (udpsession)
}
They are some interfaces with client communication.
My comments and suggestions: This data buffer is designed, code execution efficiency is not very high, and may cause errors overflow in server buffers, and some prevention measures should be added when designing.