aboutsummaryrefslogtreecommitdiff
path: root/nxcomp/Control.cpp
blob: e6693d44c6b09076a271bf07219eb3b857072f27 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
/**************************************************************************/
/*                                                                        */
/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
/*                                                                        */
/* NXCOMP, NX protocol compression and NX extensions to this software     */
/* are copyright of NoMachine. Redistribution and use of the present      */
/* software is allowed according to terms specified in the file LICENSE   */
/* which comes in the source distribution.                                */
/*                                                                        */
/* Check http://www.nomachine.com/licensing.html for applicability.       */
/*                                                                        */
/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
/*                                                                        */
/* All rights reserved.                                                   */
/*                                                                        */
/**************************************************************************/

#include "NXpack.h"

#include "Control.h"

#define PANIC
#define WARNING
#undef  TEST
#undef  DEBUG

//
// Flush immediately on prioritized messages.
//

#define FLUSH_PRIORITY                           0

//
// Maximum number of bytes sent for each token.
//

#define TOKEN_SIZE                               1536

//
// Maximum number of tokens that can be spent
// by the client proxy before having to block
// waiting for a token reply.
//

#define TOKEN_LIMIT                              24

//
// By default assume the proxy is running as a
// standalone program.
//

#define LINK_ENCRYPTED                           0

//
// Maximum number of pids the proxy will record
// and kill at shutdown.
//

#define KILL_LIMIT                               16

//
// Allocate on the NX client side channels whose
// ids are a multiple of 8 (starting from 0). All
// the other ids can be used to allocate channels
// at the NX server side (X client side).
//

#define CHANNEL_MASK                             0x07

//
// Kill session if control parameters cannot be
// negotiated before this timeout.
//

#define INIT_TIMEOUT                             60000

//
// Enter the congestion state if the remote does
// not reply to a ping within the given amount
// of time.
//

#define PING_TIMEOUT                             5000

//
// Only send one motion event any N milliseconds.
//

#define MOTION_TIMEOUT                           0


//
// Force an update of the congestion counter if
// the proxy is idle for this time.
//

#define IDLE_TIMEOUT                             50

//
// Close X connection if can't write before this
// timeout.
//

#define CHANNEL_TIMEOUT                          10000

//
// Warn user (or close proxy connection) if don't
// receive any data before this timeout.
//

#define PROXY_TIMEOUT                            120000

//
// How many milliseconds to wait for the shared
// memory completion event to become available.
//

#define SHMEM_TIMEOUT                            200
//
// Before closing down the proxy, wait for the
// given amount of miliseconds to let all the
// running applications to close down their
// connections.
//
// A null timeout will cause the proxy to wait
// indefinitely, until the watchdog process is
// killed. This is usually the way the proxy is
// started by the NX server. If on the other
// hand a timeout is given and there no channel
// is remaining, the proxy will be closed down
// using a small timeout, presently of 500 ms.
//

#define CLEANUP_TIMEOUT                          3000

//
// Wait this amount of milliseconds after any
// iteration of the house-keeping process.
//

#define KEEPER_TIMEOUT                           60000

//
// In case of timeout, select can return control
// to program earlier or later of this amount of
// ms. Consider this when calculating if timeout
// is elapsed.
//

#define LATENCY_TIMEOUT                          1

//
// Control memory allocation in transport
// and other classes.
//

#define TRANSPORT_X_BUFFER_SIZE                  131072
#define TRANSPORT_PROXY_BUFFER_SIZE              65536
#define TRANSPORT_GENERIC_BUFFER_SIZE            16384

#define TRANSPORT_X_BUFFER_THRESHOLD             262144
#define TRANSPORT_PROXY_BUFFER_THRESHOLD         131072
#define TRANSPORT_GENERIC_BUFFER_THRESHOLD       32768

//
// Never allow buffers to exceed this limit.
//

#define TRANSPORT_MAXIMUM_BUFFER_SIZE            393216

//
// Immediately flush the accumulated data to
// the X server if the write buffer exceeds
// this size.
//

#define TRANSPORT_FLUSH_BUFFER_SIZE              16384

//
// Defaults used for socket options.
//

#define OPTION_PROXY_KEEP_ALIVE                  0
#define OPTION_PROXY_LOW_DELAY                   1
#define OPTION_PROXY_CLIENT_NO_DELAY             1
#define OPTION_PROXY_SERVER_NO_DELAY             1
#define OPTION_CLIENT_NO_DELAY                   1
#define OPTION_SERVER_NO_DELAY                   1

#define OPTION_PROXY_RECEIVE_BUFFER              -1
#define OPTION_CLIENT_RECEIVE_BUFFER             -1
#define OPTION_SERVER_RECEIVE_BUFFER             -1

#define OPTION_PROXY_SEND_BUFFER                 -1
#define OPTION_CLIENT_SEND_BUFFER                -1
#define OPTION_SERVER_SEND_BUFFER                -1

#define OPTION_PROXY_RETRY_CONNECT               30
#define OPTION_PROXY_RETRY_ACCEPT                3
#define OPTION_SERVER_RETRY_CONNECT              3

//
// Defaults used for cache persistence.
//

#define PERSISTENT_CACHE_THRESHOLD               102400

#define PERSISTENT_CACHE_ENABLE_LOAD             1
#define PERSISTENT_CACHE_ENABLE_SAVE             1

#define PERSISTENT_CACHE_CHECK_ON_SHUTDOWN       0

#define PERSISTENT_CACHE_LOAD_PACKED             1
#define PERSISTENT_CACHE_LOAD_RENDER             1

#define PERSISTENT_CACHE_DISK_LIMIT              33554432

//
// Defaults used for image cache.
//

#define IMAGE_CACHE_ENABLE_LOAD                  0
#define IMAGE_CACHE_ENABLE_SAVE                  0

#define IMAGE_CACHE_DISK_LIMIT                   33554432

//
// Suggested defaults for read length parameters
// used by read buffer classes.
//

#define CLIENT_INITIAL_READ_SIZE                 8192
#define CLIENT_MAXIMUM_BUFFER_SIZE               262144

#define SERVER_INITIAL_READ_SIZE                 8192
#define SERVER_MAXIMUM_BUFFER_SIZE               65536

#define PROXY_INITIAL_READ_SIZE                  65536
#define PROXY_MAXIMUM_BUFFER_SIZE                262144 + 1024

#define GENERIC_INITIAL_READ_SIZE                8192
#define GENERIC_MAXIMUM_BUFFER_SIZE              8192

//
// Calculate bitrate in given time frames.
// Values are in milliseconds.
//

#define SHORT_BITRATE_TIME_FRAME                 5000
#define LONG_BITRATE_TIME_FRAME                  30000

//
// Bandwidth control. A value of 0 means no
// limit. Values are stored internally in
// bytes per second.
//

#define CLIENT_BITRATE_LIMIT                     0
#define SERVER_BITRATE_LIMIT                     0

//
// Default values for cache control. We limit
// the maximum size of a request to 262144 but
// we need to consider the replies, whose size
// may be up to 4MB.
//

#define MINIMUM_MESSAGE_SIZE                     4
#define MAXIMUM_MESSAGE_SIZE                     4194304
#define MAXIMUM_REQUEST_SIZE                     262144

#define CLIENT_TOTAL_STORAGE_SIZE                8388608
#define SERVER_TOTAL_STORAGE_SIZE                8388608

#define STORE_TIME_LIMIT                         3600

#define STORE_HITS_LOAD_BONUS                    10
#define STORE_HITS_ADD_BONUS                     20
#define STORE_HITS_LIMIT                         100

#define STORE_HITS_TOUCH                         1
#define STORE_HITS_UNTOUCH                       2

//
// Default parameters for message splitting.
//

#define SPLIT_MODE                               1
#define SPLIT_TIMEOUT                            50
#define SPLIT_TOTAL_SIZE                         128
#define SPLIT_TOTAL_STORAGE_SIZE                 1048576
#define SPLIT_DATA_THRESHOLD                     65536
#define SPLIT_DATA_PACKET_LIMIT                  24576

//
// Agent related parameters.
//

#define PACK_METHOD                              63
#define PACK_QUALITY                             9
#define HIDE_RENDER                              0
#define TAINT_REPLIES                            1
#define TAINT_THRESHOLD                          8

//
// In current version only X server support is
// implemented. Note that use of shared memory
// is negotiated according to options provided
// by the user.
//

#define SHMEM_CLIENT                             0
#define SHMEM_SERVER                             1

//
// Default size of shared memory segments used
// in MIT-SHM support.
//

#define SHMEM_CLIENT_SIZE                        0
#define SHMEM_SERVER_SIZE                        2097152

//
// What do we do at the end of session? If this
// flag is set, we launch a new client letting
// the user run a new NX session.
//

#define ENABLE_RESTART_ON_SHUTDOWN               0

//
// Do we produce a core dump on fatal errors?
//

#define ENABLE_CORE_DUMP_ON_ABORT                0

//
// Reopen the log file if it exceeds this size.
//

#define FILE_SIZE_LIMIT                          60000000

//
// Check periodically if we need to truncate the
// log file. By default check every minute.
//

#define FILE_SIZE_CHECK_TIMEOUT                  60000

//
// Set defaults for control. They should be what
// you get in case of 'local' connection.
//

Control::Control()
{
  ProxyMode   = proxy_undefined;
  ProxyStage  = stage_undefined;
  SessionMode = session_undefined;
  FlushPolicy = policy_undefined;
  LinkMode    = link_undefined;

  LinkEncrypted = LINK_ENCRYPTED;
  FlushPriority = FLUSH_PRIORITY;

  TokenSize  = TOKEN_SIZE;
  TokenLimit = TOKEN_LIMIT;

  ChannelMask = CHANNEL_MASK;

  InitTimeout   = INIT_TIMEOUT;
  PingTimeout   = PING_TIMEOUT;
  MotionTimeout = MOTION_TIMEOUT;
  IdleTimeout   = IDLE_TIMEOUT;

  ChannelTimeout = CHANNEL_TIMEOUT;
  ProxyTimeout   = PROXY_TIMEOUT;
  ShmemTimeout   = SHMEM_TIMEOUT;

  CleanupTimeout  = CLEANUP_TIMEOUT;
  KeeperTimeout   = KEEPER_TIMEOUT;
  LatencyTimeout  = LATENCY_TIMEOUT;

  FileSizeLimit        = FILE_SIZE_LIMIT;
  FileSizeCheckTimeout = FILE_SIZE_CHECK_TIMEOUT;

  EnableRestartOnShutdown = ENABLE_RESTART_ON_SHUTDOWN;

  KillDaemonOnShutdownLimit = KILL_LIMIT;

  KillDaemonOnShutdown = new int[KillDaemonOnShutdownLimit];

  for (int i = 0; i < KILL_LIMIT; i++)
  {
    KillDaemonOnShutdown[i] = -1;
  }

  KillDaemonOnShutdownNumber = 0;

  EnableCoreDumpOnAbort = ENABLE_CORE_DUMP_ON_ABORT;

  //
  // Collect statistics by default.
  //

  EnableStatistics = 1;

  //
  // Memory restrictions if any.
  //

  LocalMemoryLevel = -1;

  //
  // Compression must be negotiated between proxies.
  //

  LocalDeltaCompression   = -1;
  RemoteDeltaCompression  = -1;

  LocalDataCompression    = -1;
  LocalStreamCompression  = -1;

  RemoteDataCompression   = -1;
  RemoteStreamCompression = -1;

  LocalDataCompressionLevel     = -1;
  LocalDataCompressionThreshold = -1;
  LocalStreamCompressionLevel   = -1;

  RemoteDataCompressionLevel    = -1;
  RemoteStreamCompressionLevel  = -1;

  //
  // Transport buffers' allocation parameters.
  // 

  TransportXBufferSize            = TRANSPORT_X_BUFFER_SIZE;
  TransportProxyBufferSize        = TRANSPORT_PROXY_BUFFER_SIZE;
  TransportGenericBufferSize      = TRANSPORT_GENERIC_BUFFER_SIZE;

  TransportXBufferThreshold       = TRANSPORT_X_BUFFER_THRESHOLD;
  TransportProxyBufferThreshold   = TRANSPORT_PROXY_BUFFER_THRESHOLD;
  TransportGenericBufferThreshold = TRANSPORT_GENERIC_BUFFER_THRESHOLD;

  TransportMaximumBufferSize      = TRANSPORT_MAXIMUM_BUFFER_SIZE;

  //
  // Flush the write buffer if it exceeds
  // this size.
  //

  TransportFlushBufferSize = TRANSPORT_FLUSH_BUFFER_SIZE;

  //
  // Socket options.
  //

  OptionProxyKeepAlive      = OPTION_PROXY_KEEP_ALIVE;
  OptionProxyLowDelay       = OPTION_PROXY_LOW_DELAY;
  OptionProxyClientNoDelay  = OPTION_PROXY_CLIENT_NO_DELAY;
  OptionProxyServerNoDelay  = OPTION_PROXY_SERVER_NO_DELAY;
  OptionClientNoDelay       = OPTION_CLIENT_NO_DELAY;
  OptionServerNoDelay       = OPTION_SERVER_NO_DELAY;

  OptionProxyReceiveBuffer  = OPTION_PROXY_RECEIVE_BUFFER;
  OptionClientReceiveBuffer = OPTION_CLIENT_RECEIVE_BUFFER;
  OptionServerReceiveBuffer = OPTION_SERVER_RECEIVE_BUFFER;

  OptionProxySendBuffer     = OPTION_PROXY_SEND_BUFFER;
  OptionClientSendBuffer    = OPTION_CLIENT_SEND_BUFFER;
  OptionServerSendBuffer    = OPTION_SERVER_SEND_BUFFER;

  OptionProxyRetryAccept    = OPTION_PROXY_RETRY_ACCEPT;
  OptionProxyRetryConnect   = OPTION_PROXY_RETRY_CONNECT;
  OptionServerRetryConnect  = OPTION_SERVER_RETRY_CONNECT;

  //
  // Base NX directories.
  //

  HomePath   = NULL;
  RootPath   = NULL;
  SystemPath = NULL;
  TempPath   = NULL;
  ClientPath = NULL;

  //
  // Set defaults for handling persistent cache.
  //

  PersistentCachePath = NULL;
  PersistentCacheName = NULL;

  PersistentCacheThreshold = PERSISTENT_CACHE_THRESHOLD;

  PersistentCacheEnableLoad = PERSISTENT_CACHE_ENABLE_LOAD;
  PersistentCacheEnableSave = PERSISTENT_CACHE_ENABLE_SAVE;

  PersistentCacheCheckOnShutdown = PERSISTENT_CACHE_CHECK_ON_SHUTDOWN;

  PersistentCacheLoadPacked = PERSISTENT_CACHE_LOAD_PACKED;
  PersistentCacheLoadRender = PERSISTENT_CACHE_LOAD_RENDER;

  PersistentCacheDiskLimit = PERSISTENT_CACHE_DISK_LIMIT;

  //
  // Set defaults for image cache.
  //

  ImageCachePath = NULL;

  ImageCacheEnableLoad = IMAGE_CACHE_ENABLE_LOAD;
  ImageCacheEnableSave = IMAGE_CACHE_ENABLE_SAVE;

  ImageCacheDiskLimit = IMAGE_CACHE_DISK_LIMIT;

  //
  // Set defaults for the read buffers.
  //

  ClientInitialReadSize    = CLIENT_INITIAL_READ_SIZE;
  ClientMaximumBufferSize  = CLIENT_MAXIMUM_BUFFER_SIZE;

  ServerInitialReadSize    = SERVER_INITIAL_READ_SIZE;
  ServerMaximumBufferSize  = SERVER_MAXIMUM_BUFFER_SIZE;

  ProxyInitialReadSize     = PROXY_INITIAL_READ_SIZE;
  ProxyMaximumBufferSize   = PROXY_MAXIMUM_BUFFER_SIZE;

  GenericInitialReadSize   = GENERIC_INITIAL_READ_SIZE;
  GenericMaximumBufferSize = GENERIC_MAXIMUM_BUFFER_SIZE;

  ShortBitrateTimeFrame = SHORT_BITRATE_TIME_FRAME;
  LongBitrateTimeFrame  = LONG_BITRATE_TIME_FRAME;

  //
  // Bandwidth control.
  //

  LocalBitrateLimit   = -1;

  ClientBitrateLimit = CLIENT_BITRATE_LIMIT;
  ServerBitrateLimit = SERVER_BITRATE_LIMIT;

  //
  // Default parameters for message handling.
  //

  ClientTotalStorageSize = CLIENT_TOTAL_STORAGE_SIZE;
  ServerTotalStorageSize = SERVER_TOTAL_STORAGE_SIZE;

  LocalTotalStorageSize  = -1;
  RemoteTotalStorageSize = -1;

  StoreTimeLimit = STORE_TIME_LIMIT;

  StoreHitsLoadBonus = STORE_HITS_LOAD_BONUS;
  StoreHitsAddBonus  = STORE_HITS_ADD_BONUS;
  StoreHitsLimit     = STORE_HITS_LIMIT;

  StoreHitsTouch   = STORE_HITS_TOUCH;
  StoreHitsUntouch = STORE_HITS_UNTOUCH;

  MinimumMessageSize = MINIMUM_MESSAGE_SIZE;
  MaximumMessageSize = MAXIMUM_MESSAGE_SIZE;
  MaximumRequestSize = MAXIMUM_REQUEST_SIZE;

  SplitMode             = SPLIT_MODE;
  SplitTimeout          = SPLIT_TIMEOUT;
  SplitTotalSize        = SPLIT_TOTAL_SIZE;
  SplitTotalStorageSize = SPLIT_TOTAL_STORAGE_SIZE;
  SplitDataThreshold    = SPLIT_DATA_THRESHOLD;
  SplitDataPacketLimit  = SPLIT_DATA_PACKET_LIMIT;

  PackMethod     = PACK_METHOD;
  PackQuality    = PACK_QUALITY;
  HideRender     = HIDE_RENDER;
  TaintReplies   = TAINT_REPLIES;
  TaintThreshold = TAINT_THRESHOLD;

  ShmemClient = SHMEM_CLIENT;
  ShmemServer = SHMEM_SERVER;

  ShmemClientSize = SHMEM_CLIENT_SIZE;
  ShmemServerSize = SHMEM_SERVER_SIZE;

  //
  // Get local version number from compile time
  // settings. Version of remote proxy will be
  // checked at connection time.
  //

  RemoteVersionMajor = -1;
  RemoteVersionMinor = -1;
  RemoteVersionPatch = -1;

  CompatVersionMajor = -1;
  CompatVersionMinor = -1;
  CompatVersionPatch = -1;

  char version[32];

  strcpy(version, VERSION);

  char *value;

  value = strtok(version, ".");

  for (int i = 0; value != NULL && i < 3; i++)
  {
    switch (i)
    {
      case 0:

        LocalVersionMajor = atoi(value);

        break;

      case 1:

        LocalVersionMinor = atoi(value);

        break;

      case 2:

        LocalVersionPatch = atoi(value);

        break;
    }

    value = strtok(NULL, ".");
  }

  #ifdef TEST
  *logofs << "Control: Major version is " << LocalVersionMajor
          << " minor is " << LocalVersionMinor << " patch is "
          << LocalVersionPatch << ".\n" << logofs_flush;
  #endif

  //
  // Initialize local implemented methods later
  // and negotiate remote methods at connection
  // time.
  //

  LocalUnpackMethods  = NULL;
  RemoteUnpackMethods = NULL;

  //
  // Set to 1 those methods which are implemented.
  //

  setLocalUnpackMethods();

  //
  // Set the protocol version at the
  // time the session is negotiated.
  //

  protoStep6_ = 0;
  protoStep7_ = 0;
  protoStep8_ = 0;
  protoStep9_ = 0;
}

Control::~Control()
{
  if (KillDaemonOnShutdown != NULL)
  {
    delete [] KillDaemonOnShutdown;
  }

  if (HomePath != NULL)
  {
    delete [] HomePath;
  }

  if (RootPath != NULL)
  {
    delete [] RootPath;
  }

  if (SystemPath != NULL)
  {
    delete [] SystemPath;
  }

  if (TempPath != NULL)
  {
    delete [] TempPath;
  }

  if (ClientPath != NULL)
  {
    delete [] ClientPath;
  }

  if (PersistentCachePath != NULL)
  {
    delete [] PersistentCachePath;
  }

  if (PersistentCacheName != NULL)
  {
    delete [] PersistentCacheName;
  }

  if (LocalUnpackMethods != NULL)
  {
    delete [] LocalUnpackMethods;
  }

  if (RemoteUnpackMethods != NULL)
  {
    delete [] RemoteUnpackMethods;
  }

  if (ImageCachePath != NULL)
  {
    delete [] ImageCachePath;
  }
}

//
// Set the protocol step based on the
// remote version.
//

void Control::setProtoStep(int step)
{
  switch (step)
  {
    case 6:
    {
      protoStep6_ = 1;
      protoStep7_ = 0;
      protoStep8_ = 0;
      protoStep9_ = 0;

      break;
    }
    case 7:
    {
      protoStep6_ = 1;
      protoStep7_ = 1;
      protoStep8_ = 0;
      protoStep9_ = 0;

      break;
    }
    case 8:
    {
      protoStep6_ = 1;
      protoStep7_ = 1;
      protoStep8_ = 1;
      protoStep9_ = 0;

      break;
    }
    case 9:
    {
      protoStep6_ = 1;
      protoStep7_ = 1;
      protoStep8_ = 1;
      protoStep9_ = 1;

      break;
    }
    default:
    {
      #ifdef PANIC
      *logofs << "Control: PANIC! Invalid protocol step "
              << "with value " << step << ".\n"
              << logofs_flush;
      #endif

      HandleCleanup();
    }
  }
}

int Control::getProtoStep()
{
  if (protoStep9_ == 1)
  {
    return 9;
  }
  else if (protoStep8_ == 1)
  {
    return 8;
  }
  else if (protoStep7_ == 1)
  {
    return 7;
  }
  else if (protoStep6_ == 1)
  {
    return 6;
  }
  else
  {
    #ifdef PANIC
    *logofs << "Control: PANIC! Can't identify the "
            << "protocol step.\n" << logofs_flush;
    #endif

    HandleCleanup();
  }
}

//
// Set here the pack/unpack methods that are
// implemented by this NX proxy.
//

void Control::setLocalUnpackMethods()
{
  LocalUnpackMethods  = new unsigned char[PACK_METHOD_LIMIT];
  RemoteUnpackMethods = new unsigned char[PACK_METHOD_LIMIT];

  for (int i = 0; i < PACK_METHOD_LIMIT; i++)
  {
    LocalUnpackMethods[i]  = 0;
    RemoteUnpackMethods[i] = 0;
  }

  LocalUnpackMethods[NO_PACK]                         = 1;

  LocalUnpackMethods[PACK_MASKED_8_COLORS]            = 1;
  LocalUnpackMethods[PACK_MASKED_64_COLORS]           = 1;
  LocalUnpackMethods[PACK_MASKED_256_COLORS]          = 1;
  LocalUnpackMethods[PACK_MASKED_512_COLORS]          = 1;
  LocalUnpackMethods[PACK_MASKED_4K_COLORS]           = 1;
  LocalUnpackMethods[PACK_MASKED_32K_COLORS]          = 1;
  LocalUnpackMethods[PACK_MASKED_64K_COLORS]          = 1;
  LocalUnpackMethods[PACK_MASKED_256K_COLORS]         = 1;
  LocalUnpackMethods[PACK_MASKED_2M_COLORS]           = 1;
  LocalUnpackMethods[PACK_MASKED_16M_COLORS]          = 1;

  LocalUnpackMethods[PACK_RAW_8_BITS]                 = 1;
  LocalUnpackMethods[PACK_RAW_16_BITS]                = 1;
  LocalUnpackMethods[PACK_RAW_24_BITS]                = 1;

  LocalUnpackMethods[PACK_COLORMAP_256_COLORS]        = 1;

  LocalUnpackMethods[PACK_JPEG_8_COLORS]              = 1;
  LocalUnpackMethods[PACK_JPEG_64_COLORS]             = 1;
  LocalUnpackMethods[PACK_JPEG_256_COLORS]            = 1;
  LocalUnpackMethods[PACK_JPEG_512_COLORS]            = 1;
  LocalUnpackMethods[PACK_JPEG_4K_COLORS]             = 1;
  LocalUnpackMethods[PACK_JPEG_32K_COLORS]            = 1;
  LocalUnpackMethods[PACK_JPEG_64K_COLORS]            = 1;
  LocalUnpackMethods[PACK_JPEG_256K_COLORS]           = 1;
  LocalUnpackMethods[PACK_JPEG_2M_COLORS]             = 1;
  LocalUnpackMethods[PACK_JPEG_16M_COLORS]            = 1;

  LocalUnpackMethods[PACK_PNG_8_COLORS]               = 1;
  LocalUnpackMethods[PACK_PNG_64_COLORS]              = 1;
  LocalUnpackMethods[PACK_PNG_256_COLORS]             = 1;
  LocalUnpackMethods[PACK_PNG_512_COLORS]             = 1;
  LocalUnpackMethods[PACK_PNG_4K_COLORS]              = 1;
  LocalUnpackMethods[PACK_PNG_32K_COLORS]             = 1;
  LocalUnpackMethods[PACK_PNG_64K_COLORS]             = 1;
  LocalUnpackMethods[PACK_PNG_256K_COLORS]            = 1;
  LocalUnpackMethods[PACK_PNG_2M_COLORS]              = 1;
  LocalUnpackMethods[PACK_PNG_16M_COLORS]             = 1;

  LocalUnpackMethods[PACK_RGB_16M_COLORS]             = 1;
  LocalUnpackMethods[PACK_RLE_16M_COLORS]             = 1;

  LocalUnpackMethods[PACK_ALPHA]                      = 1;
  LocalUnpackMethods[PACK_COLORMAP]                   = 1;

  LocalUnpackMethods[PACK_BITMAP_16M_COLORS]          = 1;
}