]> git.stg.codes - stg.git/blob - stglibs/ia_auth_c.lib/ia_auth_c.cpp
Break internal classes to interface and implementation
[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 * Maxim Mamontov <faust@stargazer.dp.ua>
27 * Andrey Rakhmanov <andrey_rakhmanov@yahoo.com> - bugfixes.
28 */
29
30 //---------------------------------------------------------------------------
31
32 #include <cstdio>
33 #include <cstdlib>
34 #include <cstring>
35 #include <cassert>
36
37 #ifdef WIN32
38     #include <winsock2.h>
39     #include <windows.h>
40     #include <winbase.h>
41     #include <winnt.h>
42 #else
43     #include <fcntl.h>
44     #include <sys/types.h>
45     #include <sys/socket.h>
46     #include <netdb.h>
47     #include <netinet/in.h>
48     #include <arpa/inet.h>
49     #include <unistd.h>
50 #endif
51
52 #include "common.h"
53 #include "ia_auth_c.h"
54
55 #define IA_NONE            (0)
56 #define IA_CONNECT         (1)
57 #define IA_DISCONNECT      (2)
58
59 #define IA_DEBUGPROTO   1
60
61 #define IA_ID "00100"
62 //---------------------------------------------------------------------------
63 //---------------------------------------------------------------------------
64 //---------------------------------------------------------------------------
65 #ifndef WIN32
66 #include <sys/time.h>
67 void * RunL(void * data)
68 {
69
70 IA_CLIENT_PROT * c = (IA_CLIENT_PROT *)data;
71 static int a = 0;
72
73 if (a == 0)
74     {
75     usleep(50000);
76     a = 1;
77     }
78
79 while (c->GetNonstop())
80     {
81     c->Run();
82     }
83 return NULL;
84 }
85 //---------------------------------------------------------------------------
86 void Sleep(int ms)
87 {
88 usleep(ms * 1000);
89 }
90 //---------------------------------------------------------------------------
91 long GetTickCount()
92 {
93 struct timeval tv;
94 gettimeofday(&tv, NULL);
95 return tv.tv_sec*1000 + tv.tv_usec/1000;
96 }
97 #else
98 //---------------------------------------------------------------------------
99 unsigned long WINAPI RunW(void * data)
100 {
101 IA_CLIENT_PROT * c = (IA_CLIENT_PROT *)data;
102 while (c->GetNonstop())
103     c->Run();
104 return 0;
105 }
106 //---------------------------------------------------------------------------
107 #endif
108 //---------------------------------------------------------------------------
109 //---------------------------------------------------------------------------
110 //---------------------------------------------------------------------------
111 IA_CLIENT_PROT::IA_CLIENT_PROT(const string & sn, unsigned short p, uint16_t localPort)
112     : action(IA_NONE),
113       phase(1),
114       phaseTime(0),
115       codeError(0),
116       nonstop(false),
117       isNetPrepared(false),
118       proxyMode(false),
119       serverName(sn),
120       port(p),
121       ip(0),
122       localPort(localPort),
123       firstConnect(true),
124       reconnect(0),
125       sockr(0),
126       protNum(0),
127       userTimeout(60),
128       aliveTimeout(5),
129       rnd(0),
130       pStatusChangedCb(NULL),
131       pStatChangedCb(NULL),
132       pInfoCb(NULL),
133       pErrorCb(NULL),
134       pDirNameCb(NULL),
135       statusChangedCbData(NULL),
136       statChangedCbData(NULL),
137       infoCbData(NULL),
138       errorCbData(NULL),
139       dirNameCbData(NULL),
140       connSyn8(NULL),
141       connSynAck8(NULL),
142       connAck8(NULL),
143       aliveSyn8(NULL),
144       aliveAck8(NULL),
145       disconnSyn8(NULL),
146       disconnSynAck8(NULL),
147       disconnAck8(NULL),
148       info(NULL)
149 {
150 memset(&stat, 0, sizeof(stat));
151
152 #ifdef WIN32
153 WSAStartup(MAKEWORD(2, 0), &wsaData);
154 #endif
155
156 packetTypes["CONN_SYN"] = CONN_SYN_N;
157 packetTypes["CONN_SYN_ACK"] = CONN_SYN_ACK_N;
158 packetTypes["CONN_ACK"] = CONN_ACK_N;
159 packetTypes["ALIVE_SYN"] = ALIVE_SYN_N;
160 packetTypes["ALIVE_ACK"] = ALIVE_ACK_N;
161 packetTypes["DISCONN_SYN"] = DISCONN_SYN_N;
162 packetTypes["DISCONN_SYN_ACK"] = DISCONN_SYN_ACK_N;
163 packetTypes["DISCONN_ACK"] = DISCONN_ACK_N;
164 packetTypes["FIN"] = FIN_N;
165 packetTypes["ERR"] = ERROR_N;
166 packetTypes["INFO"] = INFO_N;
167 packetTypes["INFO_7"] = INFO_7_N;
168 packetTypes["INFO_8"] = INFO_8_N;
169
170 unsigned char key[IA_PASSWD_LEN];
171 memset(key, 0, IA_PASSWD_LEN);
172 strncpy((char *)key, "pr7Hhen", 8);
173 Blowfish_Init(&ctxHdr, key, IA_PASSWD_LEN);
174
175 memset(key, 0, IA_PASSWD_LEN);
176 Blowfish_Init(&ctxPass, key, IA_PASSWD_LEN);
177
178 for (size_t i = 0; i < DIR_NUM; ++i)
179     {
180     selectedDirs[i] = false;
181     }
182
183 servAddr.sin_family = AF_INET;
184 servAddr.sin_port = htons(port);
185 servAddr.sin_addr.s_addr = ip;
186 }
187 //---------------------------------------------------------------------------
188 void IA_CLIENT_PROT::PrepareNet()
189 {
190 struct hostent * phe;
191 unsigned long ip;
192
193 ip = inet_addr(serverName.c_str());
194 if (ip == INADDR_NONE)
195     {
196     phe = gethostbyname(serverName.c_str());
197     if (phe)
198         {
199         ip = *((unsigned long*)phe->h_addr_list[0]);
200         }
201     else
202         {
203         strError = string("Unknown host ") + "\'" + serverName + "\'";
204         codeError = IA_GETHOSTBYNAME_ERROR;
205         if (pErrorCb != NULL)
206             pErrorCb(strError, IA_GETHOSTBYNAME_ERROR, errorCbData);
207         }
208     }
209
210 #ifndef WIN32
211 close(sockr);
212 #else
213 closesocket(sockr);
214 #endif
215
216 sockr = socket(AF_INET, SOCK_DGRAM, 0);
217
218 struct sockaddr_in  localAddrR;
219 localAddrR.sin_family = AF_INET;
220
221 if (localPort)
222     localAddrR.sin_port = htons(localPort);
223 else
224     localAddrR.sin_port = htons(port);
225 localAddrR.sin_addr.s_addr = inet_addr("0.0.0.0");
226
227 servAddr.sin_family = AF_INET;
228 servAddr.sin_port = htons(port);
229 servAddr.sin_addr.s_addr = ip;
230
231 int res = bind(sockr, (struct sockaddr*)&localAddrR, sizeof(localAddrR));
232 if (res == -1)
233     {
234     strError = "bind error";
235     codeError = IA_BIND_ERROR;
236     if (pErrorCb != NULL)
237         pErrorCb(strError, IA_BIND_ERROR, errorCbData);
238     return;
239     }
240
241 #ifdef WIN32
242 unsigned long arg = 1;
243 res = ioctlsocket(sockr, FIONBIO, &arg);
244 #else
245 if (0 != fcntl(sockr, F_SETFL, O_NONBLOCK))
246     {
247     strError = "fcntl error";
248     codeError = IA_FCNTL_ERROR;
249     if (pErrorCb != NULL)
250         pErrorCb(strError, IA_FCNTL_ERROR, errorCbData);
251     }
252 #endif
253
254 }
255 //---------------------------------------------------------------------------
256 IA_CLIENT_PROT::~IA_CLIENT_PROT()
257 {
258 #ifndef WIN32
259 close(sockr);
260 #else
261 closesocket(sockr);
262 WSACleanup();
263 #endif
264 }
265 //---------------------------------------------------------------------------
266 int IA_CLIENT_PROT::DeterminatePacketType(const char * buffer)
267 {
268 map<string, int>::iterator pi;
269 pi = packetTypes.find(buffer);
270 if (pi == packetTypes.end())
271     {
272     return -1;
273     }
274 else
275     {
276     return pi->second;
277     }
278 }
279 //---------------------------------------------------------------------------
280 void IA_CLIENT_PROT::FillHdr8(char * buffer, unsigned long)
281 {
282 strncpy(buffer, IA_ID, 6);
283 buffer[IA_MAGIC_LEN] = 0;
284 buffer[IA_MAGIC_LEN + 1] = IA_PROTO_VER;
285 strncpy(buffer + sizeof(HDR_8), login.c_str(), IA_LOGIN_LEN);
286 }
287 //---------------------------------------------------------------------------
288 int IA_CLIENT_PROT::Send(char * buffer, int len)
289 {
290 if (!isNetPrepared)
291     {
292     PrepareNet();
293     isNetPrepared = true;
294     }
295
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 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 nonstop = true;
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 //---------------------------------------------------------------------------