]> git.stg.codes - stg.git/blob - stglibs/ia_auth_c.lib/ia_auth_c.cpp
Додано заголовочні файлі фреймворка для unit-тестування TUT
[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 #ifdef WIN32
425 unsigned long pt;
426 CreateThread(NULL, 16384, RunW, this, 0, &pt);
427 #else
428 pthread_create(&thread, NULL, RunL, this);
429 #endif
430 }
431 //---------------------------------------------------------------------------
432 void IA_CLIENT_PROT::Stop()
433 {
434 nonstop = false;
435 }
436 //---------------------------------------------------------------------------
437 void IA_CLIENT_PROT::Run()
438 {
439 NetRecv();
440
441 switch (phase)
442     {
443     case 1:
444         if (action == IA_CONNECT)
445             {
446             action = IA_NONE;
447             NetSend(CONN_SYN_N);
448             phase = 2;
449             phaseTime = GetTickCount();
450             }
451         if (reconnect && !firstConnect)
452             {
453             action = IA_CONNECT;
454             }
455         break;
456
457     case 2:
458         if ((int)(GetTickCount() - phaseTime)/1000 > aliveTimeout)
459             {
460             phase = 1;
461             phaseTime = GetTickCount();
462             if (pStatusChangedCb != NULL)
463                 pStatusChangedCb(0, statusChangedCbData);
464             }
465
466         if (action == IA_DISCONNECT)
467             {
468             action = IA_NONE;
469             NetSend(DISCONN_SYN_N);
470             phase = 4;
471             phaseTime = GetTickCount();
472             }
473
474         break;
475
476     case 3:
477         if ((int)(GetTickCount() - phaseTime)/1000 > userTimeout)
478             {
479             phase = 1;
480             phaseTime = GetTickCount();
481             if (pStatusChangedCb != NULL)
482                 pStatusChangedCb(0, statusChangedCbData);
483             firstConnect = false;
484             }
485
486         if (action == IA_DISCONNECT)
487             {
488             action = IA_NONE;
489             NetSend(DISCONN_SYN_N);
490             phase = 4;
491             phaseTime = GetTickCount();
492             }
493
494         break;
495
496     case 4:
497         if ((int)(GetTickCount() - phaseTime)/1000 > aliveTimeout)
498             {
499             phase=1;
500             phaseTime = GetTickCount();
501             if (pStatusChangedCb != NULL)
502                 pStatusChangedCb(0, statusChangedCbData);
503             }
504
505         if (action == IA_CONNECT)
506             {
507             action = IA_NONE;
508             NetSend(CONN_SYN_N);
509             phase = 2;
510             phaseTime = GetTickCount();
511             }
512
513         break;
514
515     case 5:
516         if ((int)(GetTickCount() - phaseTime)/1000 > aliveTimeout)
517             {
518             phase = 1;
519             phaseTime = GetTickCount();
520             if (pStatusChangedCb != NULL)
521                 pStatusChangedCb(0, statusChangedCbData);
522             }
523
524         if (action == IA_CONNECT)
525             {
526             action = IA_NONE;
527             NetSend(CONN_SYN_N);
528             phase = 2;
529             phaseTime = GetTickCount();
530             }
531
532         break;
533     }
534 Sleep(20);
535 return;
536 }
537 //---------------------------------------------------------------------------
538 void IA_CLIENT_PROT::GetStat(LOADSTAT * ls)
539 {
540 memcpy(ls, &stat, sizeof(stat));
541 }
542 //---------------------------------------------------------------------------
543 void IA_CLIENT_PROT::SetServer(const string & sn, unsigned short p)
544 {
545 serverName = sn;
546 port = p;
547 PrepareNet();
548 }
549 //---------------------------------------------------------------------------
550 void IA_CLIENT_PROT::SetLogin(const string & l)
551 {
552 login = l;
553 }
554 //---------------------------------------------------------------------------
555 void IA_CLIENT_PROT::SetPassword(const string & p)
556 {
557 password = p;
558
559 unsigned char keyL[IA_PASSWD_LEN];
560 memset(keyL, 0, IA_PASSWD_LEN);
561 strncpy((char *)keyL, password.c_str(), IA_PASSWD_LEN);
562 Blowfish_Init(&ctxPass, keyL, IA_PASSWD_LEN);
563 }
564 //---------------------------------------------------------------------------
565 void IA_CLIENT_PROT::SetEnabledDirs(const bool * selectedDirs)
566 {
567 memcpy(IA_CLIENT_PROT::selectedDirs, selectedDirs, sizeof(bool) * DIR_NUM);
568 }
569 //---------------------------------------------------------------------------
570 int IA_CLIENT_PROT::Connect()
571 {
572 action = IA_CONNECT;
573 return 0;
574 }
575 //---------------------------------------------------------------------------
576 int IA_CLIENT_PROT::Disconnect()
577 {
578 firstConnect = true;
579 action = IA_DISCONNECT;
580 return 0;
581 }
582 //---------------------------------------------------------------------------
583 int IA_CLIENT_PROT::GetStrError(string * error) const
584 {
585 int ret = codeError;
586 *error = strError;
587 strError = "";
588 codeError = 0;
589 return ret;
590 }
591 //---------------------------------------------------------------------------
592 int IA_CLIENT_PROT::Process_CONN_SYN_ACK_8(const char * buffer)
593 {
594 vector<string> dirNames;
595 connSynAck8 = (CONN_SYN_ACK_8*)buffer;
596
597 #ifdef ARCH_BE
598 SwapBytes(connSynAck8->len);
599 SwapBytes(connSynAck8->rnd);
600 SwapBytes(connSynAck8->userTimeOut);
601 SwapBytes(connSynAck8->aliveDelay);
602 #endif
603
604 rnd = connSynAck8->rnd;
605 userTimeout = connSynAck8->userTimeOut;
606 aliveTimeout = connSynAck8->aliveDelay;
607
608 for (int i = 0; i < DIR_NUM; i++)
609     {
610     dirNames.push_back((const char*)connSynAck8->dirName[i]);
611     }
612
613 if (pDirNameCb != NULL)
614     pDirNameCb(dirNames, dirNameCbData);
615
616 NetSend(CONN_ACK_N);
617 phase = 3;
618 phaseTime = GetTickCount();
619
620 return CONN_SYN_ACK_N;
621 }
622 //---------------------------------------------------------------------------
623 int IA_CLIENT_PROT::Process_ALIVE_SYN_8(const char * buffer)
624 {
625 aliveSyn8 = (ALIVE_SYN_8*)buffer;
626
627 #ifdef ARCH_BE
628 SwapBytes(aliveSyn8->len);
629 SwapBytes(aliveSyn8->rnd);
630 SwapBytes(aliveSyn8->cash);
631 SwapBytes(aliveSyn8->status);
632 for (int i = 0; i < DIR_NUM; ++i)
633     {
634     SwapBytes(aliveSyn8->mu[i]);
635     SwapBytes(aliveSyn8->md[i]);
636     SwapBytes(aliveSyn8->su[i]);
637     SwapBytes(aliveSyn8->sd[i]);
638     }
639 #endif
640
641 rnd = aliveSyn8->rnd;
642 memcpy(&stat, (char*)aliveSyn8->mu, sizeof(stat));
643
644 if (pStatChangedCb != NULL)
645     pStatChangedCb(stat, statChangedCbData);
646
647 if (pStatusChangedCb != NULL)
648     pStatusChangedCb(1, statusChangedCbData);
649 NetSend(ALIVE_ACK_N);
650 phaseTime = GetTickCount();
651
652 return ALIVE_SYN_N;
653 }
654 //---------------------------------------------------------------------------
655 int IA_CLIENT_PROT::Process_DISCONN_SYN_ACK_8(const char * buffer)
656 {
657 disconnSynAck8 = (DISCONN_SYN_ACK_8*)buffer;
658
659 #ifdef ARCH_BE
660 SwapBytes(disconnSynAck8->len);
661 SwapBytes(disconnSynAck8->rnd);
662 #endif
663
664 rnd = disconnSynAck8->rnd;
665
666 NetSend(DISCONN_ACK_N);
667 phase = 5;
668 phaseTime = GetTickCount();
669
670 return DISCONN_SYN_ACK_N;
671 }
672 //---------------------------------------------------------------------------
673 int IA_CLIENT_PROT::Process_FIN_8(const char *)
674 {
675 phase = 1;
676 phaseTime = GetTickCount();
677 if (pStatusChangedCb != NULL)
678     pStatusChangedCb(0, statusChangedCbData);
679
680 return FIN_N;
681 }
682 //---------------------------------------------------------------------------
683 int IA_CLIENT_PROT::Process_INFO_8(const char * buffer)
684 {
685 info = (INFO_8*)buffer;
686
687 #ifdef ARCH_BE
688 SwapBytes(info->len);
689 SwapBytes(info->sendTime);
690 #endif
691
692 if (pInfoCb != NULL)
693     pInfoCb((char*)info->text, info->infoType, info->showTime, info->sendTime, infoCbData);
694 return INFO_8_N;
695 }
696 //---------------------------------------------------------------------------
697 int IA_CLIENT_PROT::Process_ERROR(const char * buffer)
698 {
699 memcpy(&err, buffer, sizeof(err));
700
701 #ifdef ARCH_BE
702 SwapBytes(err.len);
703 #endif
704
705 KOIToWin((const char*)err.text, &messageText);
706 if (pErrorCb != NULL)
707     pErrorCb(messageText, IA_SERVER_ERROR, errorCbData);
708 phase = 1;
709 phaseTime = GetTickCount();
710 codeError = IA_SERVER_ERROR;
711
712 return ERROR_N;
713 }
714 //---------------------------------------------------------------------------
715 int IA_CLIENT_PROT::Prepare_CONN_SYN_8(char * buffer)
716 {
717 connSyn8 = (CONN_SYN_8*)buffer;
718
719 #ifdef ARCH_BE
720 SwapBytes(connSyn8->len);
721 #endif
722
723 assert(sizeof(CONN_SYN_8) == Min8(sizeof(CONN_SYN_8)) && "CONN_SYN_8 is not aligned to 8 bytes");
724
725 connSyn8->len = sizeof(CONN_SYN_8);
726 strncpy((char*)connSyn8->type, "CONN_SYN", IA_MAX_TYPE_LEN);
727 strncpy((char*)connSyn8->login, login.c_str(), IA_LOGIN_LEN);
728 connSyn8->dirs = 0;
729 for (int i = 0; i < DIR_NUM; i++)
730     {
731     connSyn8->dirs |= (selectedDirs[i] << i);
732     }
733 return connSyn8->len;
734 }
735 //---------------------------------------------------------------------------
736 int IA_CLIENT_PROT::Prepare_CONN_ACK_8(char * buffer)
737 {
738 connAck8 = (CONN_ACK_8*)buffer;
739
740 #ifdef ARCH_BE
741 SwapBytes(connAck8->len);
742 SwapBytes(connAck8->rnd);
743 #endif
744
745 assert(sizeof(CONN_ACK_8) == Min8(sizeof(CONN_ACK_8)) && "CONN_ACK_8 is not aligned to 8 bytes");
746
747 connAck8->len = sizeof(CONN_ACK_8);
748 strncpy((char*)connAck8->loginS, login.c_str(), IA_LOGIN_LEN);
749 strncpy((char*)connAck8->type, "CONN_ACK", IA_MAX_TYPE_LEN);
750 rnd++;
751 connAck8->rnd = rnd;
752
753 return connAck8->len;
754 }
755 //---------------------------------------------------------------------------
756 int IA_CLIENT_PROT::Prepare_ALIVE_ACK_8(char * buffer)
757 {
758 aliveAck8 = (ALIVE_ACK_8*)buffer;
759
760 #ifdef ARCH_BE
761 SwapBytes(aliveAck8->len);
762 SwapBytes(aliveAck8->rnd);
763 #endif
764
765 assert(Min8(sizeof(ALIVE_ACK_8)) == sizeof(ALIVE_ACK_8) && "ALIVE_ACK_8 is not aligned to 8 bytes");
766
767 aliveAck8 = (ALIVE_ACK_8*)buffer;
768 aliveAck8->len = sizeof(ALIVE_ACK_8);
769 strncpy((char*)aliveAck8->loginS, login.c_str(), IA_LOGIN_LEN);
770 strncpy((char*)aliveAck8->type, "ALIVE_ACK", IA_MAX_TYPE_LEN);
771 aliveAck8->rnd = ++rnd;
772 return aliveAck8->len;
773 }
774 //---------------------------------------------------------------------------
775 int IA_CLIENT_PROT::Prepare_DISCONN_SYN_8(char * buffer)
776 {
777 disconnSyn8 = (DISCONN_SYN_8*)buffer;
778
779 #ifdef ARCH_BE
780 SwapBytes(disconnSyn8->len);
781 #endif
782
783 assert(Min8(sizeof(DISCONN_SYN_8)) == sizeof(DISCONN_SYN_8) && "DISCONN_SYN_8 is not aligned to 8 bytes");
784
785 disconnSyn8->len = sizeof(DISCONN_SYN_8);
786 strncpy((char*)disconnSyn8->loginS, login.c_str(), IA_LOGIN_LEN);
787 strncpy((char*)disconnSyn8->type, "DISCONN_SYN", IA_MAX_TYPE_LEN);
788 strncpy((char*)disconnSyn8->login, login.c_str(), IA_LOGIN_LEN);
789 return disconnSyn8->len;
790 }
791 //---------------------------------------------------------------------------
792 int IA_CLIENT_PROT::Prepare_DISCONN_ACK_8(char * buffer)
793 {
794 disconnAck8 = (DISCONN_ACK_8*)buffer;
795
796 #ifdef ARCH_BE
797 SwapBytes(disconnAck8->len);
798 SwapBytes(disconnAck8->rnd);
799 #endif
800
801 assert(Min8(sizeof(DISCONN_ACK_8)) == sizeof(DISCONN_ACK_8) && "DISCONN_ACK_8 is not aligned to 8 bytes");
802
803 disconnAck8->len = Min8(sizeof(DISCONN_ACK_8));
804 disconnAck8->rnd = rnd + 1;
805 strncpy((char*)disconnAck8->loginS, login.c_str(), IA_LOGIN_LEN);
806 strncpy((char*)disconnAck8->type, "DISCONN_ACK", IA_MAX_TYPE_LEN);
807 return disconnAck8->len;
808 }
809 //---------------------------------------------------------------------------
810 void IA_CLIENT_PROT::SetStatusChangedCb(tpStatusChangedCb p, void * data)
811 {
812 pStatusChangedCb = p;
813 statusChangedCbData = data;
814 }
815 //---------------------------------------------------------------------------
816 void IA_CLIENT_PROT::SetStatChangedCb(tpStatChangedCb p, void * data)
817 {
818 pStatChangedCb = p;
819 statChangedCbData = data;
820 }
821 //---------------------------------------------------------------------------
822 void IA_CLIENT_PROT::SetInfoCb(tpCallBackInfoFn p, void * data)
823 {
824 pInfoCb = p;
825 infoCbData = data;
826 }
827 //---------------------------------------------------------------------------
828 void IA_CLIENT_PROT::SetDirNameCb(tpCallBackDirNameFn p, void * data)
829 {
830 pDirNameCb = p;
831 dirNameCbData = data;
832 }
833 //---------------------------------------------------------------------------
834 void IA_CLIENT_PROT::SetErrorCb(tpCallBackErrorFn p, void * data)
835 {
836 pErrorCb = p;
837 errorCbData = data;
838 }
839 //---------------------------------------------------------------------------