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