1152
|
1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
2 /*
|
|
3 $Id: tcphandle.c 1162 2000-11-28 02:22:42Z warmenhoven $
|
|
4 $Log$
|
|
5 Revision 1.1 2000/11/28 02:22:42 warmenhoven
|
|
6 icq. whoop de doo
|
|
7
|
|
8 Revision 1.12 2000/07/09 22:19:35 bills
|
|
9 added new *Close functions, use *Close functions instead of *Delete
|
|
10 where correct, and misc cleanup
|
|
11
|
|
12 Revision 1.11 2000/06/25 16:36:16 denis
|
|
13 '\n' was added at the end of log messages.
|
|
14
|
|
15 Revision 1.10 2000/05/04 15:57:20 bills
|
|
16 Reworked file transfer notification, small bugfixes, and cleanups.
|
|
17
|
|
18 Revision 1.9 2000/05/03 18:29:15 denis
|
|
19 Callbacks have been moved to the ICQLINK structure.
|
|
20
|
|
21 Revision 1.8 2000/04/05 14:37:02 denis
|
|
22 Applied patch from "Guillaume R." <grs@mail.com> for basic Win32
|
|
23 compatibility.
|
|
24
|
|
25 Revision 1.7 2000/01/20 20:06:00 bills
|
|
26 removed debugging printfs
|
|
27
|
|
28 Revision 1.6 2000/01/20 19:59:15 bills
|
|
29 first implementation of sending file requests
|
|
30
|
|
31 Revision 1.5 1999/11/30 09:51:42 bills
|
|
32 more file xfer logic added
|
|
33
|
|
34 Revision 1.4 1999/11/11 15:10:30 guruz
|
|
35 - Added Base for Webpager Messages. Please type "make fixme"
|
|
36 - Removed Segfault when kicq is started the first time
|
|
37
|
|
38 Revision 1.3 1999/10/01 02:28:51 bills
|
|
39 icq_TCPProcessHello returns something now :)
|
|
40
|
|
41 Revision 1.2 1999/10/01 00:49:20 lord
|
|
42 some compilation problems are fixed.
|
|
43
|
|
44 Revision 1.1 1999/09/29 19:47:21 bills
|
|
45 reworked chat/file handling. fixed chat. (it's been broke since I put
|
|
46 non-blocking connects in)
|
|
47
|
|
48 Revision 1.15 1999/07/16 15:45:59 denis
|
|
49 Cleaned up.
|
|
50
|
|
51 Revision 1.14 1999/07/16 12:10:10 denis
|
|
52 tcp_packet* functions renamed to icq_Packet*
|
|
53 Cleaned up.
|
|
54
|
|
55 Revision 1.13 1999/07/12 15:13:41 cproch
|
|
56 - added definition of ICQLINK to hold session-specific global variabled
|
|
57 applications which have more than one connection are now possible
|
|
58 - changed nearly every function defintion to support ICQLINK parameter
|
|
59
|
|
60 Revision 1.12 1999/06/30 13:51:25 bills
|
|
61 cleanups
|
|
62
|
|
63 Revision 1.11 1999/05/03 21:41:30 bills
|
|
64 initial file xfer support added- untested
|
|
65
|
|
66 Revision 1.10 1999/04/29 09:36:06 denis
|
|
67 Cleanups, warning removed
|
|
68
|
|
69 Revision 1.9 1999/04/17 19:40:33 bills
|
|
70 reworked code to use icq_TCPLinks instead of icq_ContactItem entries.
|
|
71 modified ProcessChatPacket to negotiate both sending and receiving chat
|
|
72 requests properly.
|
|
73
|
|
74 Revision 1.8 1999/04/14 15:12:02 denis
|
|
75 Cleanups for "strict" compiling (-ansi -pedantic)
|
|
76 icq_ContactItem parameter added to function icq_TCPOnMessageReceived()
|
|
77 Segfault fixed on spoofed messages.
|
|
78
|
|
79 */
|
|
80
|
|
81 #include <time.h>
|
|
82
|
|
83 #ifndef _WIN32
|
|
84 #include <unistd.h>
|
|
85 #endif
|
|
86
|
|
87 #include "icqtypes.h"
|
|
88 #include "icq.h"
|
|
89 #include "icqlib.h"
|
|
90
|
|
91 #include "tcp.h"
|
|
92 #include "stdpackets.h"
|
|
93 #include "tcplink.h"
|
|
94
|
|
95 void icq_TCPOnMessageReceived(ICQLINK *link, DWORD uin, const char *message, DWORD id, icq_TCPLink *plink);
|
|
96 void icq_TCPOnURLReceived(ICQLINK *link, DWORD uin, const char *message, DWORD id);
|
|
97 void icq_TCPOnChatReqReceived(ICQLINK *link, DWORD uin, const char *message, DWORD id);
|
|
98 void icq_TCPOnFileReqReceived(ICQLINK *link, DWORD uin, const char *message,
|
|
99 const char *filename, unsigned long filesize, DWORD id);
|
|
100 void icq_TCPProcessAck(ICQLINK *link, icq_Packet *p);
|
|
101 void icq_HandleChatAck(icq_TCPLink *plink, icq_Packet *p, int port);
|
|
102 void icq_HandleChatHello(icq_TCPLink *plink);
|
|
103 void icq_HandleFileHello(icq_TCPLink *plink);
|
|
104 void icq_HandleFileAck(icq_TCPLink *plink, icq_Packet *p, int port);
|
|
105
|
|
106 void icq_TCPProcessPacket(icq_Packet *p, icq_TCPLink *plink)
|
|
107 {
|
|
108 DWORD uin;
|
|
109 WORD version;
|
|
110 WORD command;
|
|
111 WORD type;
|
|
112 WORD status;
|
|
113 DWORD command_type;
|
|
114 DWORD filesize = 0;
|
|
115 DWORD port = 0;
|
|
116
|
|
117 const char *message;
|
|
118 const char *filename = 0;
|
|
119
|
|
120 icq_PacketBegin(p);
|
|
121 (void)icq_PacketRead32(p);
|
|
122 version=icq_PacketRead16(p);
|
|
123 command=icq_PacketRead16(p);
|
|
124 (void)icq_PacketRead16(p);
|
|
125
|
|
126 uin=icq_PacketRead32(p);
|
|
127 type=icq_PacketRead16(p);
|
|
128 message=icq_PacketReadString(p);
|
|
129 (void)icq_PacketRead32(p);
|
|
130 (void)icq_PacketRead32(p);
|
|
131 (void)icq_PacketRead32(p);
|
|
132 (void)icq_PacketRead8(p);
|
|
133 status=icq_PacketRead16(p);
|
|
134 command_type=icq_PacketRead16(p);
|
|
135
|
|
136 switch(type)
|
|
137 {
|
|
138 case ICQ_TCP_MSG_MSG:
|
|
139 case ICQ_TCP_MSG_URL:
|
|
140 p->id=icq_PacketRead32(p);
|
|
141 break;
|
|
142
|
|
143 case ICQ_TCP_MSG_CHAT:
|
|
144 (void)icq_PacketReadString(p);
|
|
145 (void)icq_PacketRead16(p);
|
|
146 (void)icq_PacketRead16(p);
|
|
147 port=icq_PacketRead32(p);
|
|
148 p->id=icq_PacketRead32(p);
|
|
149 break;
|
|
150
|
|
151 case ICQ_TCP_MSG_FILE:
|
|
152 (void)icq_PacketRead16(p);
|
|
153 (void)icq_PacketRead16(p);
|
|
154 filename=icq_PacketReadString(p);
|
|
155 filesize=icq_PacketRead32(p);
|
|
156 port=icq_PacketRead32(p);
|
|
157 p->id=icq_PacketRead32(p);
|
|
158 break;
|
|
159
|
|
160 default:
|
|
161 icq_FmtLog(plink->icqlink, ICQ_LOG_WARNING, "unknown message packet, type %x\n", type);
|
|
162 }
|
|
163
|
|
164 #ifdef TCP_PROCESS_TRACE
|
|
165 printf("packet processed from uin: %lu:\n", uin);
|
|
166 printf(" command: %x\ttype: %x\n", command, type);
|
|
167 printf(" status: %x\tcommand_type: %x\n", status, (int)command_type);
|
|
168 printf(" message %s\n", message);
|
|
169 printf(" id: %x\n", (int)p->id);
|
|
170 #endif
|
|
171
|
|
172 switch(command)
|
|
173 {
|
|
174 case ICQ_TCP_MESSAGE:
|
|
175 switch(type)
|
|
176 {
|
|
177 case ICQ_TCP_MSG_MSG:
|
|
178 icq_TCPOnMessageReceived(plink->icqlink, uin, message, p->id, plink);
|
|
179 break;
|
|
180
|
|
181 case ICQ_TCP_MSG_URL:
|
|
182 icq_TCPOnURLReceived(plink->icqlink, uin, message, p->id);
|
|
183 break;
|
|
184
|
|
185 case ICQ_TCP_MSG_CHAT:
|
|
186 icq_TCPOnChatReqReceived(plink->icqlink, uin, message, p->id);
|
|
187 break;
|
|
188
|
|
189 case ICQ_TCP_MSG_FILE:
|
|
190 icq_TCPOnFileReqReceived(plink->icqlink, uin, message, filename, filesize, p->id);
|
|
191 break;
|
|
192
|
|
193 default:
|
|
194 icq_FmtLog(plink->icqlink, ICQ_LOG_WARNING, "unknown message type %d!\n", type);
|
|
195 break;
|
|
196 }
|
|
197 break;
|
|
198
|
|
199 case ICQ_TCP_ACK:
|
|
200 switch(type) {
|
|
201 case ICQ_TCP_MSG_CHAT:
|
|
202 icq_HandleChatAck(plink, p, port);
|
|
203 break;
|
|
204
|
|
205 case ICQ_TCP_MSG_FILE:
|
|
206 icq_HandleFileAck(plink, p, port);
|
|
207 break;
|
|
208
|
|
209 case ICQ_TCP_MSG_MSG:
|
|
210 case ICQ_TCP_MSG_URL:
|
|
211 if(plink->icqlink->icq_RequestNotify) {
|
|
212 icq_FmtLog(plink->icqlink, ICQ_LOG_MESSAGE, "received ack %d\n", p->id);
|
|
213 (*plink->icqlink->icq_RequestNotify)(plink->icqlink, p->id, ICQ_NOTIFY_ACK, status,
|
|
214 (void *)message);
|
|
215 (*plink->icqlink->icq_RequestNotify)(plink->icqlink, p->id, ICQ_NOTIFY_SUCCESS, 0, 0);
|
|
216 }
|
|
217 break;
|
|
218 }
|
|
219 break;
|
|
220
|
|
221 case ICQ_TCP_CANCEL:
|
|
222 /* icq_TCPProcessCancel(p); */
|
|
223 break;
|
|
224
|
|
225 default:
|
|
226 icq_FmtLog(plink->icqlink, ICQ_LOG_WARNING,
|
|
227 "unknown packet command %d!\n", command);
|
|
228 }
|
|
229 }
|
|
230
|
|
231 void icq_TCPProcessCancel(icq_Packet *p)
|
|
232 {
|
|
233 (void)p;
|
|
234
|
|
235 /*
|
|
236 find packet in queue
|
|
237 call notification function
|
|
238 remove packet from queue
|
|
239 */
|
|
240 }
|
|
241
|
|
242 int icq_TCPProcessHello(icq_Packet *p, icq_TCPLink *plink)
|
|
243 {
|
|
244 /* TCP Hello packet */
|
|
245 BYTE code; /* 0xFF - init packet code */
|
|
246 DWORD version; /* tcp version */
|
|
247 DWORD remote_port; /* remote message listen port */
|
|
248 DWORD remote_uin; /* remote uin */
|
|
249 DWORD remote_ip; /* remote IP as seen by ICQ server */
|
|
250 DWORD remote_real_ip; /* remote IP as seen by client */
|
|
251 BYTE flags; /* tcp flags */
|
|
252 DWORD remote_other_port; /* remote chat or file listen port */
|
|
253
|
|
254 icq_PacketBegin(p);
|
|
255
|
|
256 code=icq_PacketRead8(p);
|
|
257 version=icq_PacketRead32(p);
|
|
258
|
|
259 if (!(p->length>=26 && code==ICQ_TCP_HELLO))
|
|
260 {
|
|
261 icq_FmtLog(plink->icqlink, ICQ_LOG_WARNING,
|
|
262 "malformed hello packet received from %s:%d, closing link\n",
|
|
263 inet_ntoa(*((struct in_addr *)(&(plink->remote_address.sin_addr)))),
|
|
264 ntohs(plink->remote_address.sin_port));
|
|
265
|
|
266 icq_TCPLinkClose(plink);
|
|
267 return 0;
|
|
268 }
|
|
269 remote_port=icq_PacketRead32(p);
|
|
270 remote_uin=icq_PacketRead32(p);
|
|
271 remote_ip=icq_PacketRead32(p);
|
|
272 remote_real_ip=icq_PacketRead32(p);
|
|
273 flags=icq_PacketRead8(p);
|
|
274 remote_other_port=icq_PacketRead32(p);
|
|
275
|
|
276 icq_FmtLog(plink->icqlink, ICQ_LOG_MESSAGE,
|
|
277 "hello packet received from %lu { version=%d }\n", remote_uin, version);
|
|
278
|
|
279 plink->remote_version=version;
|
|
280 plink->remote_uin=remote_uin;
|
|
281 plink->flags=flags;
|
|
282 plink->mode&=~TCP_LINK_MODE_HELLOWAIT;
|
|
283
|
|
284 /* file and chat sessions require additional handling */
|
|
285 if(plink->type==TCP_LINK_CHAT) icq_HandleChatHello(plink);
|
|
286 if(plink->type==TCP_LINK_FILE) icq_HandleFileHello(plink);
|
|
287
|
|
288 return 1;
|
|
289 }
|
|
290
|
|
291 void icq_TCPOnMessageReceived(ICQLINK *link, DWORD uin, const char *message, DWORD id, icq_TCPLink *plink)
|
|
292 {
|
|
293 char data[512] ;
|
|
294 #ifdef TCP_PACKET_TRACE
|
|
295 printf("tcp message packet received from %lu { sequence=%x }\n",
|
|
296 uin, (int)id);
|
|
297 #endif
|
|
298
|
|
299 if(link->icq_RecvMessage)
|
|
300 {
|
|
301 /* use the current system time for time received */
|
|
302 time_t t=time(0);
|
|
303 struct tm *ptime=localtime(&t);
|
|
304 icq_Packet *pack;
|
|
305 icq_TCPLink *preallink=icq_FindTCPLink(link, uin, TCP_LINK_MESSAGE);
|
|
306
|
|
307 strncpy(data,message,512) ;
|
|
308 icq_RusConv("wk",data) ;
|
|
309
|
|
310 (*link->icq_RecvMessage)(link, uin, ptime->tm_hour, ptime->tm_min,
|
|
311 ptime->tm_mday, ptime->tm_mon+1, ptime->tm_year+1900, data);
|
|
312
|
|
313 if(plink != preallink)
|
|
314 {
|
|
315 /* if(icq_SpoofedMessage)
|
|
316 (*icq_SpoofedMessage(uin, ...));*/
|
|
317 }
|
|
318
|
|
319 if(plink)
|
|
320 {
|
|
321 /* send an acknowledgement to the remote client */
|
|
322 pack=icq_TCPCreateMessageAck(plink,0);
|
|
323 icq_PacketAppend32(pack, id);
|
|
324 icq_PacketSend(pack, plink->socket);
|
|
325 #ifdef TCP_PACKET_TRACE
|
|
326 printf("tcp message ack sent to uin %lu { sequence=%lx }\n", uin, id);
|
|
327 #endif
|
|
328 icq_PacketDelete(pack);
|
|
329 }
|
|
330 }
|
|
331 }
|
|
332
|
|
333 void icq_TCPOnURLReceived(ICQLINK *link, DWORD uin, const char *message, DWORD id)
|
|
334 {
|
|
335 #ifdef TCP_PACKET_TRACE
|
|
336 printf("tcp url packet received from %lu { sequence=%lx }\n",
|
|
337 uin, id);
|
|
338 #endif /*TCP_PACKET_TRACE*/
|
|
339
|
|
340 if(link->icq_RecvURL) {
|
|
341
|
|
342 /* use the current system time for time received */
|
|
343 time_t t=time(0);
|
|
344 struct tm *ptime=localtime(&t);
|
|
345 icq_Packet *pack;
|
|
346 char *pfe;
|
|
347 icq_TCPLink *plink=icq_FindTCPLink(link, uin, TCP_LINK_MESSAGE);
|
|
348
|
|
349 /* the URL is split from the description by 0xFE */
|
|
350 pfe=strchr(message, '\xFE');
|
|
351 *pfe=0;
|
|
352 (*link->icq_RecvURL)(link, uin, ptime->tm_hour, ptime->tm_min,
|
|
353 ptime->tm_mday, ptime->tm_mon+1, ptime->tm_year+1900, pfe+1, message);
|
|
354
|
|
355 /* send an acknowledgement to the remote client */
|
|
356 pack=icq_TCPCreateURLAck(plink,0);
|
|
357 icq_PacketAppend32(pack, id);
|
|
358 icq_PacketSend(pack, plink->socket);
|
|
359 #ifdef TCP_PACKET_TRACE
|
|
360 printf("tcp message ack sent to %lu { sequence=%lx }\n", uin, id);
|
|
361 #endif
|
|
362 icq_PacketDelete(pack);
|
|
363 }
|
|
364 }
|
|
365
|
|
366
|