]> git.stg.codes - stg.git/blob - stglibs/ia_auth_c.lib/ia_auth_c.cpp
Додано патч від Alexey Osipov <lion-simba@pridelands.ru>
[stg.git] / stglibs / ia_auth_c.lib / ia_auth_c.cpp
1 /*
2 ** This program is free software; you can redistribute it and/or modify
3 ** it under the terms of the GNU General Public License as published by
4 ** the Free Software Foundation; either version 1, or (at your option)
5 ** any later version.
6
7 ** This program is distributed in the hope that it will be useful,
8 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
9 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 ** GNU General Public License for more details.
11
12 ** You should have received a copy of the GNU General Public License
13 ** along with this program; if not, write to the Free Software
14 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15 */
16
17 /*
18  $Author: faust $
19  $Revision: 1.15 $
20  $Date: 2010/04/16 11:28:03 $
21 */
22
23 /*
24 * Author :
25 * Boris Mikhailenko <stg34@stargazer.dp.ua>
26 * Andrey Rakhmanov <andrey_rakhmanov@yahoo.com> - èñïðàâëåíèå äâóõ áàãîâ.
27 */
28
29 //---------------------------------------------------------------------------
30
31 #include <cstdio>
32 #include <cstdlib>
33 #include <cstring>
34 #include <cassert>
35
36 #ifdef WIN32
37     #include <winsock2.h>
38     #include <windows.h>
39     #include <winbase.h>
40     #include <winnt.h>
41 #else
42     #include <fcntl.h>
43     #include <sys/types.h>
44     #include <sys/socket.h>
45     #include <netdb.h>
46     #include <netinet/in.h>
47     #include <arpa/inet.h>
48     #include <unistd.h>
49 #endif
50
51 #include "common.h"
52 #include "ia_auth_c.h"
53
54 #define IA_NONE            (0)
55 #define IA_CONNECT         (1)
56 #define IA_DISCONNECT      (2)
57
58 #define IA_DEBUGPROTO   1
59
60 #define IA_ID "00100"
61 //---------------------------------------------------------------------------
62 //---------------------------------------------------------------------------
63 //---------------------------------------------------------------------------
64 #ifndef WIN32
65 #include <sys/time.h>
66 void * RunL(void * data)
67 {
68
69 IA_CLIENT_PROT * c = (IA_CLIENT_PROT *)data;
70 static int a = 0;
71
72 if (a == 0)
73     {
74     usleep(50000);
75     a = 1;
76     }
77
78 while (c->GetNonstop())
79     {
80     c->Run();
81     }
82 return NULL;
83 }
84 //---------------------------------------------------------------------------
85 void Sleep(int ms)
86 {
87 usleep(ms * 1000);
88 }
89 //---------------------------------------------------------------------------
90 long GetTickCount()
91 {
92 struct timeval tv;
93 gettimeofday(&tv, NULL);
94 return tv.tv_sec*1000 + tv.tv_usec/1000;
95 }
96 #else
97 //---------------------------------------------------------------------------
98 unsigned long WINAPI RunW(void * data)
99 {
100 IA_CLIENT_PROT * c = (IA_CLIENT_PROT *)data;
101 while (c->GetNonstop())
102     c->Run();
103 return 0;
104 }
105 //---------------------------------------------------------------------------
106 #endif
107 //---------------------------------------------------------------------------
108 //---------------------------------------------------------------------------
109 //---------------------------------------------------------------------------
110 IA_CLIENT_PROT::IA_CLIENT_PROT(const string & sn, unsigned short p, uint16_t localPort)
111     : action(IA_NONE),
112       phase(1),
113       phaseTime(0),
114       codeError(0),
115       nonstop(false),
116       isNetPrepared(false),
117       proxyMode(false),
118       serverName(sn),
119       port(p),
120       ip(0),
121       localPort(localPort),
122       firstConnect(true),
123       reconnect(0),
124       sockr(0),
125       protNum(0),
126       userTimeout(60),
127       aliveTimeout(5),
128       rnd(0),
129       pStatusChangedCb(NULL),
130       pStatChangedCb(NULL),
131       pInfoCb(NULL),
132       pErrorCb(NULL),
133       pDirNameCb(NULL),
134       statusChangedCbData(NULL),
135       statChangedCbData(NULL),
136       infoCbData(NULL),
137       errorCbData(NULL),
138       dirNameCbData(NULL),
139       connSyn8(NULL),
140       connSynAck8(NULL),
141       connAck8(NULL),
142       aliveSyn8(NULL),
143       aliveAck8(NULL),
144       disconnSyn8(NULL),
145       disconnSynAck8(NULL),
146       disconnAck8(NULL),
147       info(NULL)
148 {
149 memset(&stat, 0, sizeof(stat));
150
151 #ifdef WIN32
152 WSAStartup(MAKEWORD(2, 0), &wsaData);
153 #endif
154
155 packetTypes["CONN_SYN"] = CONN_SYN_N;
156 packetTypes["CONN_SYN_ACK"] = CONN_SYN_ACK_N;
157 packetTypes["CONN_ACK"] = CONN_ACK_N;
158 packetTypes["ALIVE_SYN"] = ALIVE_SYN_N;
159 packetTypes["ALIVE_ACK"] = ALIVE_ACK_N;
160 packetTypes["DISCONN_SYN"] = DISCONN_SYN_N;
161 packetTypes["DISCONN_SYN_ACK"] = DISCONN_SYN_ACK_N;
162 packetTypes["DISCONN_ACK"] = DISCONN_ACK_N;
163 packetTypes["FIN"] = FIN_N;
164 packetTypes["ERR"] = ERROR_N;
165 packetTypes["INFO"] = INFO_N;
166 packetTypes["INFO_7"] = INFO_7_N;
167 packetTypes["INFO_8"] = INFO_8_N;
168
169 unsigned char key[IA_PASSWD_LEN];
170 memset(key, 0, IA_PASSWD_LEN);
171 strncpy((char *)key, "pr7Hhen", 8);
172 Blowfish_Init(&ctxHdr, key, IA_PASSWD_LEN);
173
174 memset(key, 0, IA_PASSWD_LEN);
175 Blowfish_Init(&ctxPass, key, IA_PASSWD_LEN);
176
177 for (size_t i = 0; i < DIR_NUM; ++i)
178     {
179     selectedDirs[i] = false;
180     }
181
182 servAddr.sin_family = AF_INET;
183 servAddr.sin_port = htons(port);
184 servAddr.sin_addr.s_addr = ip;
185 }
186 //---------------------------------------------------------------------------
187 void IA_CLIENT_PROT::PrepareNet()
188 {
189 struct hostent * phe;
190 unsigned long ip;
191
192 ip = inet_addr(serverName.c_str());
193 if (ip == INADDR_NONE)
194     {
195     phe = gethostbyname(serverName.c_str());
196     if (phe)
197         {
198         ip = *((unsigned long*)phe->h_addr_list[0]);
199         }
200     else
201         {
202         strError = string("Unknown host ") + "\'" + serverName + "\'";
203         codeError = IA_GETHOSTBYNAME_ERROR;
204         if (pErrorCb != NULL)
205             pErrorCb(strError, IA_GETHOSTBYNAME_ERROR, errorCbData);
206         }
207     }
208
209 #ifndef WIN32
210 close(sockr);
211 #else
212 closesocket(sockr);
213 #endif
214
215 sockr = socket(AF_INET, SOCK_DGRAM, 0);  // Cîêåò ÷åðåç êîòîðûé øëåì è ïðèíèìàåì
216
217 struct sockaddr_in  localAddrR;      // Íàø àäðåñ
218 localAddrR.sin_family = AF_INET;
219
220 if (localPort)
221     localAddrR.sin_port = htons(localPort);
222 else
223     localAddrR.sin_port = htons(port);
224 localAddrR.sin_addr.s_addr = inet_addr("0.0.0.0");
225
226 servAddr.sin_family = AF_INET;
227 servAddr.sin_port = htons(port);
228 servAddr.sin_addr.s_addr = ip;
229
230 int res = bind(sockr, (struct sockaddr*)&localAddrR, sizeof(localAddrR));
231 if (res == -1)
232     {
233     strError = "bind error";
234     codeError = IA_BIND_ERROR;
235     if (pErrorCb != NULL)
236         pErrorCb(strError, IA_BIND_ERROR, errorCbData);
237     return;
238     }
239
240 #ifdef WIN32
241 unsigned long arg = 1;
242 res = ioctlsocket(sockr, FIONBIO, &arg);
243 #else
244 if (0 != fcntl(sockr, F_SETFL, O_NONBLOCK))
245     {
246     strError = "fcntl error";
247     codeError = IA_FCNTL_ERROR;
248     if (pErrorCb != NULL)
249         pErrorCb(strError, IA_FCNTL_ERROR, errorCbData);
250     }
251 #endif
252
253 }
254 //---------------------------------------------------------------------------
255 IA_CLIENT_PROT::~IA_CLIENT_PROT()
256 {
257 #ifndef WIN32
258 close(sockr);
259 #else
260 closesocket(sockr);
261 WSACleanup();
262 #endif
263 }
264 //---------------------------------------------------------------------------
265 int IA_CLIENT_PROT::DeterminatePacketType(const char * buffer)
266 {
267 map<string, int>::iterator pi;
268 pi = packetTypes.find(buffer);
269 if (pi == packetTypes.end())
270     {
271     return -1;
272     }
273 else
274     {
275     return pi->second;
276     }
277 }
278 //---------------------------------------------------------------------------
279 void IA_CLIENT_PROT::FillHdr8(char * buffer, unsigned long)
280 {
281 strncpy(buffer, IA_ID, 6);
282 buffer[IA_MAGIC_LEN] = 0;
283 buffer[IA_MAGIC_LEN + 1] = IA_PROTO_VER;
284 strncpy(buffer + sizeof(HDR_8), login.c_str(), IA_LOGIN_LEN);
285 }
286 //---------------------------------------------------------------------------
287 int IA_CLIENT_PROT::Send(char * buffer, int len)
288 {
289 if (!isNetPrepared)
290     {
291     PrepareNet();
292     isNetPrepared = true;
293     }
294
295 // Øèôðóåì LoginS
296 int db = sizeof(HDR_8);
297 for (int i = 0; i < IA_LOGIN_LEN/8; i++)
298     {
299     Blowfish_Encrypt(&ctxHdr, (uint32_t*)(buffer + db + i*8), (uint32_t*)(buffer + db + i*8 + 4));
300     }
301
302 // Øèôðóåì âñ¸ îñòàëüíîå
303 db += IA_LOGIN_LEN;
304 int encLen = (len - sizeof(HDR_8) - IA_LOGIN_LEN)/8;
305 for (int i = 0; i < encLen; i++)
306     {
307     Blowfish_Encrypt(&ctxPass, (uint32_t*)(buffer + db), (uint32_t*)(buffer + db + 4));
308     db += 8;
309     }
310
311 return sendto(sockr, buffer, len, 0, (struct sockaddr*)&servAddr, sizeof(servAddr));
312 }
313 //---------------------------------------------------------------------------
314 int IA_CLIENT_PROT::Recv(char * buffer, int len)
315 {
316 #ifdef WIN32
317 int fromLen;
318 #else
319 socklen_t fromLen;
320 #endif
321
322 struct sockaddr_in addr;
323 fromLen = sizeof(addr);
324 int res = recvfrom(sockr, buffer, len, 0, (struct sockaddr*)&addr, &fromLen);
325
326 if (res == -1)
327     return res;
328
329 if (strcmp(buffer + 4 + sizeof(HDR_8), "ERR"))
330     {
331     for (int i = 0; i < len/8; i++)
332         Blowfish_Decrypt(&ctxPass, (uint32_t*)(buffer + i*8), (uint32_t*)(buffer + i*8 + 4));
333     }
334
335 return 0;
336 }
337 //---------------------------------------------------------------------------
338 int IA_CLIENT_PROT::NetSend(int n)
339 {
340 char buffer[2048];
341 int msgLen;
342
343 memset(buffer, 0, 2048);
344
345 switch (n)
346     {
347     case CONN_SYN_N:
348         msgLen = Prepare_CONN_SYN_8(buffer);
349         break;
350
351     case CONN_ACK_N:
352         msgLen = Prepare_CONN_ACK_8(buffer);
353         break;
354
355     case ALIVE_ACK_N:
356         msgLen = Prepare_ALIVE_ACK_8(buffer);
357         break;
358
359     case DISCONN_SYN_N:
360         msgLen = Prepare_DISCONN_SYN_8(buffer);
361         break;
362
363     case DISCONN_ACK_N:
364         msgLen = Prepare_DISCONN_ACK_8(buffer);
365         break;
366
367     default:
368         return -1;
369     }
370
371 FillHdr8(buffer, 0);
372 Send(buffer, msgLen);
373
374 return 0;
375 }
376 //---------------------------------------------------------------------------
377 int IA_CLIENT_PROT::NetRecv()
378 {
379 char buffer[2048];
380
381 if (Recv(buffer, sizeof(buffer)) < 0)
382     return -1;
383
384 char packetName[20];
385 strncpy(packetName, buffer + 12, sizeof(packetName));
386 packetName[sizeof(packetName) - 1] = 0;
387 int pn = DeterminatePacketType(buffer + 12);
388
389 int ret;
390 switch (pn)
391     {
392     case CONN_SYN_ACK_N:
393         ret = Process_CONN_SYN_ACK_8(buffer);
394         break;
395
396     case ALIVE_SYN_N:
397         ret = Process_ALIVE_SYN_8(buffer);
398         break;
399
400     case DISCONN_SYN_ACK_N:
401         ret = Process_DISCONN_SYN_ACK_8(buffer);
402         break;
403
404     case FIN_N:
405         ret = Process_FIN_8(buffer);
406         break;
407
408     case INFO_8_N:
409         ret = Process_INFO_8(buffer);
410         break;
411
412     case ERROR_N:
413         ret = Process_ERROR(buffer);
414         break;
415
416     default:
417         ret = -1;
418     }
419 return ret;
420 }
421 //---------------------------------------------------------------------------
422 void IA_CLIENT_PROT::Start()
423 {
424 nonstop = true;
425 #ifdef WIN32
426 unsigned long pt;
427 CreateThread(NULL, 16384, RunW, this, 0, &pt);
428 #else
429 pthread_create(&thread, NULL, RunL, this);
430 #endif
431 }
432 //---------------------------------------------------------------------------
433 void IA_CLIENT_PROT::Stop()
434 {
435 nonstop = false;
436 }
437 //---------------------------------------------------------------------------
438 void IA_CLIENT_PROT::Run()
439 {
440 NetRecv();
441
442 switch (phase)
443     {
444     case 1:
445         if (action == IA_CONNECT)
446             {
447             action = IA_NONE;
448             NetSend(CONN_SYN_N);
449             phase = 2;
450             phaseTime = GetTickCount();
451             }
452         if (reconnect && !firstConnect)
453             {
454             action = IA_CONNECT;
455             }
456         break;
457
458     case 2:
459         if ((int)(GetTickCount() - phaseTime)/1000 > aliveTimeout)
460             {
461             phase = 1;
462             phaseTime = GetTickCount();
463             if (pStatusChangedCb != NULL)
464                 pStatusChangedCb(0, statusChangedCbData);
465             }
466
467         if (action == IA_DISCONNECT)
468             {
469             action = IA_NONE;
470             NetSend(DISCONN_SYN_N);
471             phase = 4;
472             phaseTime = GetTickCount();
473             }
474
475         break;
476
477     case 3:
478         if ((int)(GetTickCount() - phaseTime)/1000 > userTimeout)
479             {
480             phase = 1;
481             phaseTime = GetTickCount();
482             if (pStatusChangedCb != NULL)
483                 pStatusChangedCb(0, statusChangedCbData);
484             firstConnect = false;
485             }
486
487         if (action == IA_DISCONNECT)
488             {
489             action = IA_NONE;
490             NetSend(DISCONN_SYN_N);
491             phase = 4;
492             phaseTime = GetTickCount();
493             }
494
495         break;
496
497     case 4:
498         if ((int)(GetTickCount() - phaseTime)/1000 > aliveTimeout)
499             {
500             phase=1;
501             phaseTime = GetTickCount();
502             if (pStatusChangedCb != NULL)
503                 pStatusChangedCb(0, statusChangedCbData);
504             }
505
506         if (action == IA_CONNECT)
507             {
508             action = IA_NONE;
509             NetSend(CONN_SYN_N);
510             phase = 2;
511             phaseTime = GetTickCount();
512             }
513
514         break;
515
516     case 5:
517         if ((int)(GetTickCount() - phaseTime)/1000 > aliveTimeout)
518             {
519             phase = 1;
520             phaseTime = GetTickCount();
521             if (pStatusChangedCb != NULL)
522                 pStatusChangedCb(0, statusChangedCbData);
523             }
524
525         if (action == IA_CONNECT)
526             {
527             action = IA_NONE;
528             NetSend(CONN_SYN_N);
529             phase = 2;
530             phaseTime = GetTickCount();
531             }
532
533         break;
534     }
535 Sleep(20);
536 return;
537 }
538 //---------------------------------------------------------------------------
539 void IA_CLIENT_PROT::GetStat(LOADSTAT * ls)
540 {
541 memcpy(ls, &stat, sizeof(stat));
542 }
543 //---------------------------------------------------------------------------
544 void IA_CLIENT_PROT::SetServer(const string & sn, unsigned short p)
545 {
546 serverName = sn;
547 port = p;
548 PrepareNet();
549 }
550 //---------------------------------------------------------------------------
551 void IA_CLIENT_PROT::SetLogin(const string & l)
552 {
553 login = l;
554 }
555 //---------------------------------------------------------------------------
556 void IA_CLIENT_PROT::SetPassword(const string & p)
557 {
558 password = p;
559
560 unsigned char keyL[IA_PASSWD_LEN];
561 memset(keyL, 0, IA_PASSWD_LEN);
562 strncpy((char *)keyL, password.c_str(), IA_PASSWD_LEN);
563 Blowfish_Init(&ctxPass, keyL, IA_PASSWD_LEN);
564 }
565 //---------------------------------------------------------------------------
566 void IA_CLIENT_PROT::SetEnabledDirs(const bool * selectedDirs)
567 {
568 memcpy(IA_CLIENT_PROT::selectedDirs, selectedDirs, sizeof(bool) * DIR_NUM);
569 }
570 //---------------------------------------------------------------------------
571 int IA_CLIENT_PROT::Connect()
572 {
573 action = IA_CONNECT;
574 return 0;
575 }
576 //---------------------------------------------------------------------------
577 int IA_CLIENT_PROT::Disconnect()
578 {
579 firstConnect = true;
580 action = IA_DISCONNECT;
581 return 0;
582 }
583 //---------------------------------------------------------------------------
584 int IA_CLIENT_PROT::GetStrError(string * error) const
585 {
586 int ret = codeError;
587 *error = strError;
588 strError = "";
589 codeError = 0;
590 return ret;
591 }
592 //---------------------------------------------------------------------------
593 int IA_CLIENT_PROT::Process_CONN_SYN_ACK_8(const char * buffer)
594 {
595 vector<string> dirNames;
596 connSynAck8 = (CONN_SYN_ACK_8*)buffer;
597
598 #ifdef ARCH_BE
599 SwapBytes(connSynAck8->len);
600 SwapBytes(connSynAck8->rnd);
601 SwapBytes(connSynAck8->userTimeOut);
602 SwapBytes(connSynAck8->aliveDelay);
603 #endif
604
605 rnd = connSynAck8->rnd;
606 userTimeout = connSynAck8->userTimeOut;
607 aliveTimeout = connSynAck8->aliveDelay;
608
609 for (int i = 0; i < DIR_NUM; i++)
610     {
611     dirNames.push_back((const char*)connSynAck8->dirName[i]);
612     }
613
614 if (pDirNameCb != NULL)
615     pDirNameCb(dirNames, dirNameCbData);
616
617 NetSend(CONN_ACK_N);
618 phase = 3;
619 phaseTime = GetTickCount();
620
621 return CONN_SYN_ACK_N;
622 }
623 //---------------------------------------------------------------------------
624 int IA_CLIENT_PROT::Process_ALIVE_SYN_8(const char * buffer)
625 {
626 aliveSyn8 = (ALIVE_SYN_8*)buffer;
627
628 #ifdef ARCH_BE
629 SwapBytes(aliveSyn8->len);
630 SwapBytes(aliveSyn8->rnd);
631 SwapBytes(aliveSyn8->cash);
632 SwapBytes(aliveSyn8->status);
633 for (int i = 0; i < DIR_NUM; ++i)
634     {
635     SwapBytes(aliveSyn8->mu[i]);
636     SwapBytes(aliveSyn8->md[i]);
637     SwapBytes(aliveSyn8->su[i]);
638     SwapBytes(aliveSyn8->sd[i]);
639     }
640 #endif
641
642 rnd = aliveSyn8->rnd;
643 memcpy(&stat, (char*)aliveSyn8->mu, sizeof(stat));
644
645 if (pStatChangedCb != NULL)
646     pStatChangedCb(stat, statChangedCbData);
647
648 if (pStatusChangedCb != NULL)
649     pStatusChangedCb(1, statusChangedCbData);
650 NetSend(ALIVE_ACK_N);
651 phaseTime = GetTickCount();
652
653 return ALIVE_SYN_N;
654 }
655 //---------------------------------------------------------------------------
656 int IA_CLIENT_PROT::Process_DISCONN_SYN_ACK_8(const char * buffer)
657 {
658 disconnSynAck8 = (DISCONN_SYN_ACK_8*)buffer;
659
660 #ifdef ARCH_BE
661 SwapBytes(disconnSynAck8->len);
662 SwapBytes(disconnSynAck8->rnd);
663 #endif
664
665 rnd = disconnSynAck8->rnd;
666
667 NetSend(DISCONN_ACK_N);
668 phase = 5;
669 phaseTime = GetTickCount();
670
671 return DISCONN_SYN_ACK_N;
672 }
673 //---------------------------------------------------------------------------
674 int IA_CLIENT_PROT::Process_FIN_8(const char *)
675 {
676 phase = 1;
677 phaseTime = GetTickCount();
678 if (pStatusChangedCb != NULL)
679     pStatusChangedCb(0, statusChangedCbData);
680
681 return FIN_N;
682 }
683 //---------------------------------------------------------------------------
684 int IA_CLIENT_PROT::Process_INFO_8(const char * buffer)
685 {
686 info = (INFO_8*)buffer;
687
688 #ifdef ARCH_BE
689 SwapBytes(info->len);
690 SwapBytes(info->sendTime);
691 #endif
692
693 if (pInfoCb != NULL)
694     pInfoCb((char*)info->text, info->infoType, info->showTime, info->sendTime, infoCbData);
695 return INFO_8_N;
696 }
697 //---------------------------------------------------------------------------
698 int IA_CLIENT_PROT::Process_ERROR(const char * buffer)
699 {
700 memcpy(&err, buffer, sizeof(err));
701
702 #ifdef ARCH_BE
703 SwapBytes(err.len);
704 #endif
705
706 KOIToWin((const char*)err.text, &messageText);
707 if (pErrorCb != NULL)
708     pErrorCb(messageText, IA_SERVER_ERROR, errorCbData);
709 phase = 1;
710 phaseTime = GetTickCount();
711 codeError = IA_SERVER_ERROR;
712
713 return ERROR_N;
714 }
715 //---------------------------------------------------------------------------
716 int IA_CLIENT_PROT::Prepare_CONN_SYN_8(char * buffer)
717 {
718 connSyn8 = (CONN_SYN_8*)buffer;
719
720 #ifdef ARCH_BE
721 SwapBytes(connSyn8->len);
722 #endif
723
724 assert(sizeof(CONN_SYN_8) == Min8(sizeof(CONN_SYN_8)) && "CONN_SYN_8 is not aligned to 8 bytes");
725
726 connSyn8->len = sizeof(CONN_SYN_8);
727 strncpy((char*)connSyn8->type, "CONN_SYN", IA_MAX_TYPE_LEN);
728 strncpy((char*)connSyn8->login, login.c_str(), IA_LOGIN_LEN);
729 connSyn8->dirs = 0;
730 for (int i = 0; i < DIR_NUM; i++)
731     {
732     connSyn8->dirs |= (selectedDirs[i] << i);
733     }
734 return connSyn8->len;
735 }
736 //---------------------------------------------------------------------------
737 int IA_CLIENT_PROT::Prepare_CONN_ACK_8(char * buffer)
738 {
739 connAck8 = (CONN_ACK_8*)buffer;
740
741 #ifdef ARCH_BE
742 SwapBytes(connAck8->len);
743 SwapBytes(connAck8->rnd);
744 #endif
745
746 assert(sizeof(CONN_ACK_8) == Min8(sizeof(CONN_ACK_8)) && "CONN_ACK_8 is not aligned to 8 bytes");
747
748 connAck8->len = sizeof(CONN_ACK_8);
749 strncpy((char*)connAck8->loginS, login.c_str(), IA_LOGIN_LEN);
750 strncpy((char*)connAck8->type, "CONN_ACK", IA_MAX_TYPE_LEN);
751 rnd++;
752 connAck8->rnd = rnd;
753
754 return connAck8->len;
755 }
756 //---------------------------------------------------------------------------
757 int IA_CLIENT_PROT::Prepare_ALIVE_ACK_8(char * buffer)
758 {
759 aliveAck8 = (ALIVE_ACK_8*)buffer;
760
761 #ifdef ARCH_BE
762 SwapBytes(aliveAck8->len);
763 SwapBytes(aliveAck8->rnd);
764 #endif
765
766 assert(Min8(sizeof(ALIVE_ACK_8)) == sizeof(ALIVE_ACK_8) && "ALIVE_ACK_8 is not aligned to 8 bytes");
767
768 aliveAck8 = (ALIVE_ACK_8*)buffer;
769 aliveAck8->len = sizeof(ALIVE_ACK_8);
770 strncpy((char*)aliveAck8->loginS, login.c_str(), IA_LOGIN_LEN);
771 strncpy((char*)aliveAck8->type, "ALIVE_ACK", IA_MAX_TYPE_LEN);
772 aliveAck8->rnd = ++rnd;
773 return aliveAck8->len;
774 }
775 //---------------------------------------------------------------------------
776 int IA_CLIENT_PROT::Prepare_DISCONN_SYN_8(char * buffer)
777 {
778 disconnSyn8 = (DISCONN_SYN_8*)buffer;
779
780 #ifdef ARCH_BE
781 SwapBytes(disconnSyn8->len);
782 #endif
783
784 assert(Min8(sizeof(DISCONN_SYN_8)) == sizeof(DISCONN_SYN_8) && "DISCONN_SYN_8 is not aligned to 8 bytes");
785
786 disconnSyn8->len = sizeof(DISCONN_SYN_8);
787 strncpy((char*)disconnSyn8->loginS, login.c_str(), IA_LOGIN_LEN);
788 strncpy((char*)disconnSyn8->type, "DISCONN_SYN", IA_MAX_TYPE_LEN);
789 strncpy((char*)disconnSyn8->login, login.c_str(), IA_LOGIN_LEN);
790 return disconnSyn8->len;
791 }
792 //---------------------------------------------------------------------------
793 int IA_CLIENT_PROT::Prepare_DISCONN_ACK_8(char * buffer)
794 {
795 disconnAck8 = (DISCONN_ACK_8*)buffer;
796
797 #ifdef ARCH_BE
798 SwapBytes(disconnAck8->len);
799 SwapBytes(disconnAck8->rnd);
800 #endif
801
802 assert(Min8(sizeof(DISCONN_ACK_8)) == sizeof(DISCONN_ACK_8) && "DISCONN_ACK_8 is not aligned to 8 bytes");
803
804 disconnAck8->len = Min8(sizeof(DISCONN_ACK_8));
805 disconnAck8->rnd = rnd + 1;
806 strncpy((char*)disconnAck8->loginS, login.c_str(), IA_LOGIN_LEN);
807 strncpy((char*)disconnAck8->type, "DISCONN_ACK", IA_MAX_TYPE_LEN);
808 return disconnAck8->len;
809 }
810 //---------------------------------------------------------------------------
811 void IA_CLIENT_PROT::SetStatusChangedCb(tpStatusChangedCb p, void * data)
812 {
813 pStatusChangedCb = p;
814 statusChangedCbData = data;
815 }
816 //---------------------------------------------------------------------------
817 void IA_CLIENT_PROT::SetStatChangedCb(tpStatChangedCb p, void * data)
818 {
819 pStatChangedCb = p;
820 statChangedCbData = data;
821 }
822 //---------------------------------------------------------------------------
823 void IA_CLIENT_PROT::SetInfoCb(tpCallBackInfoFn p, void * data)
824 {
825 pInfoCb = p;
826 infoCbData = data;
827 }
828 //---------------------------------------------------------------------------
829 void IA_CLIENT_PROT::SetDirNameCb(tpCallBackDirNameFn p, void * data)
830 {
831 pDirNameCb = p;
832 dirNameCbData = data;
833 }
834 //---------------------------------------------------------------------------
835 void IA_CLIENT_PROT::SetErrorCb(tpCallBackErrorFn p, void * data)
836 {
837 pErrorCb = p;
838 errorCbData = data;
839 }
840 //---------------------------------------------------------------------------