-
Notifications
You must be signed in to change notification settings - Fork 5
/
globals.h
2675 lines (2422 loc) · 81.9 KB
/
globals.h
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
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#ifndef GLOBALS_H_
#define GLOBALS_H_
#define _GNU_SOURCE // needed for PTHREAD_MUTEX_RECURSIVE on some plattforms and maybe other things; do not remove
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#include <assert.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <poll.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/mman.h>
#include <stdarg.h>
#include <time.h>
#include <sys/time.h>
#include <limits.h>
#include <pwd.h>
#include <netinet/tcp.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <string.h>
#include <strings.h>
#include <signal.h>
#include <errno.h>
#include <pthread.h>
#include <dirent.h>
#include <termios.h>
#include <inttypes.h>
#include <sys/utsname.h>
#if !defined(__APPLE__)
#include <sys/sysmacros.h>
#endif
/*
* The following hack is taken from Linux: include/linux/kconfig.h
* Original comment follows:
* Getting something that works in C and CPP for an arg that may or may
* not be defined is tricky. Here, if we have "#define CONFIG_BOOGER 1"
* we match on the placeholder define, insert the "0," for arg1 and generate
* the triplet (0, 1, 0). Then the last step cherry picks the 2nd arg (a one).
* When CONFIG_BOOGER is not defined, we generate a (... 1, 0) pair, and when
* the last step cherry picks the 2nd arg, we get a zero.
*/
#define __ARG_PLACEHOLDER_1 0,
#define config_enabled(cfg) _config_enabled(cfg)
#define _config_enabled(value) __config_enabled(__ARG_PLACEHOLDER_##value)
#define __config_enabled(arg1_or_junk) ___config_enabled(arg1_or_junk 1, 0)
#define ___config_enabled(__ignored, val, ...) val
#include "config.h"
#if defined(WITH_SSL) && !defined(WITH_LIBCRYPTO)
# define WITH_LIBCRYPTO 1
#endif
/* For deprecated but still needed cryptography functions:
* 10002 corresponds to OpenSSL version 1.0.2*/
#define OPENSSL_API_COMPAT 10002
#if defined(__CYGWIN__) || defined(__arm__) || defined(__SH4__) || defined(__MIPS__) || defined(__MIPSEL__) || defined(__powerpc__)
# define CS_LOGFILE "/dev/tty"
#endif
#if defined(__AIX__) || defined(__SGI__) || defined(__OSF__) || defined(__HPUX__) || defined(__SOLARIS__) || defined(__APPLE__)
# define NEED_DAEMON
#endif
#if defined(__AIX__) || defined(__SGI__) || defined(__OSF__) || defined(__HPUX__) || defined(__SOLARIS__) || defined(__CYGWIN__)
# define NO_ENDIAN_H
#endif
#if defined(__AIX__) || defined(__SGI__)
# define socklen_t unsigned long
#endif
#if defined(__SOLARIS__) || defined(__FreeBSD__) || defined(__OpenBSD__)
# define BSD_COMP
#endif
#if defined(__HPUX__)
# define _XOPEN_SOURCE_EXTENDED
#endif
#if (defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__)) && !defined(s6_addr32)
#define s6_addr32 __u6_addr.__u6_addr32
#endif
#ifdef __ANDROID__
#ifndef in_port_t
#define in_port_t uint16_t
#endif
#define tcdrain(fd) ioctl(fd, TCSBRK, 1)
#endif
#ifdef __uClinux__
#define fork() 0
#endif
// Prevent warnings about openssl functions. Apple may consider 'openssl'
// deprecated but changing perfectly working portable code just because they
// introduced some proprietary API is not going to happen.
#if defined(__APPLE__)
#define __AVAILABILITY_MACROS_USES_AVAILABILITY 0
#define MAC_OS_X_VERSION_MIN_REQUIRED MAC_OS_X_VERSION_10_6
#endif
#include "cscrypt/aes.h"
#ifdef IPV6SUPPORT
#define IN_ADDR_T struct in6_addr
#define SOCKADDR sockaddr_storage
#define ADDR_ANY in6addr_any
#define DEFAULT_AF AF_INET6
#else
#define IN_ADDR_T in_addr_t
#define SOCKADDR sockaddr_in
#define ADDR_ANY INADDR_ANY
#define DEFAULT_AF AF_INET
#endif
#ifndef NO_ENDIAN_H
#if defined(__APPLE__)
#include <machine/endian.h>
#define __BYTE_ORDER __DARWIN_BYTE_ORDER
#define __BIG_ENDIAN __DARWIN_BIG_ENDIAN
#define __LITTLE_ENDIAN __DARWIN_LITTLE_ENDIAN
#elif defined(__FreeBSD__) || defined(__OpenBSD__)
#include <sys/endian.h>
#define __BYTE_ORDER _BYTE_ORDER
#define __BIG_ENDIAN _BIG_ENDIAN
#define __LITTLE_ENDIAN _LITTLE_ENDIAN
#else
#include <endian.h>
#include <byteswap.h>
#endif
#endif
/* ===========================
* macros
* =========================== */
// Prevent use of unsafe functions (doesn't work for MacOSX)
#if !defined(__APPLE__)
#define strcpy(a,b) UNSAFE_STRCPY_USE_CS_STRNCPY_INSTEAD()
#define sprintf(a,...) UNSAFE_SPRINTF_USE_SNPRINTF_INSTEAD()
#define strtok(a,b,c) UNSAFE_STRTOK_USE_STRTOK_R_INSTEAD()
#define gmtime(a) UNSAFE_GMTIME_NOT_THREADSAFE_USE_CS_GMTIME_R()
#define localtime(a) UNSAFE_LOCALTIME_NOT_THREADSAFE_USE_LOCALTIME_R()
#define asctime(a) UNSAFE_ASCTIME_NOT_THREADSAFE_USE_ASCTIME_R()
#define ctime(a) UNSAFE_CTIME_NOT_THREADSAFE_USE_CS_CTIME_R()
#define gethostbyaddr(a,b,c) UNSAFE_GETHOSTBYADDR_NOT_THREADSAFE_USE_GETADDRINFO()
#define gethostent(a) UNSAFE_GETHOSTENT_NOT_THREADSAFE()
#define getprotobyname(a) UNSAFE_GETPROTOBYNAME_NOT_THREADSAFE_USE_GETPROTOBYNAME_R()
#define getservbyname(a,b) UNSAFE_GETSERVBYNAME_NOT_THREADSAFE_USE_GETSERVBYNAME_R()
#define getservbyport(a,b) UNSAFE_GETSERVBYPORT_NOT_THREADSAFE_USE_GETSERVBYPORT_R()
#define getservent() UNSAFE_GETSERVENT_NOT_THREADSAFE_USE_GETSERVENT_R()
#define getnetbyname(a) UNSAFE_GETNETBYNAME_NOT_THREADSAFE_USE_GETNETBYNAME_R
#define getnetbyaddr(a,b) UNSAFE_GETNETBYADDR_NOT_THREADSAFE_USE_GETNETBYADDR_R
#define getnetent() UNSAFE_GETNETENT_NOT_THREADSAFE_USE_GETNETENT_R
#define getrpcbyname(a) UNSAFE_GETRPCBYNAME_NOT_THREADSAFE_USE_GETRPCBYNAME_R
#define getrpcbynumber(a) UNSAFE_GETRPCBYNUMBER_NOT_THREADSAFE_USE_GETRPCBYNUMBER_R
#define getrpcent() UNSAFE_GETRPCENT_NOT_THREADSAFE_USE_GETRPCENT_R
#define ctermid(a) UNSAFE_CTERMID_NOT_THREADSAFE_USE_CTERMID_R
#define tmpnam(a) UNSAFE_TMPNAM_NOT_THREADSAFE
#define tempnam(a,b) UNSAFE_TEMPNAM_NOT_THREADSAFE
#define getlogin() UNSAFE_GETLOGIN_NOT_THREADSAFE_USE_GETLOGIN_R
#define getpwnam(a) UNSAFE_GETPWNAM_NOT_THREADSAFE_USE_GETPWNAM_R
#define getpwent() UNSAFE_GETPWENT_NOT_THREADSAFE_USE_GETPWENT_R
#define fgetpwent(a) UNSAFE_FGETPWENT_NOT_THREADSAFE_USE_FGETPWENT_R
#ifndef __ANDROID__
#define getpwuid(a) UNSAFE_GETPWUID_NOT_THREADSAFE_USE_GETPWUID_R
#endif
#define getspent() UNSAFE_GETSPENT_NOT_THREADSAFE_USE_GETSPENT_R
#define getspnam(a) UNSAFE_GETSPNAM_NOT_THREADSAFE_USE_GETSPNAM_R
#define fgetspent(a) UNSAFE_FGETSPENT_NOT_THREADSAFE_USE_FGETSPENT_R
#define getgrnam(a) UNSAFE_GETGRNAM_NOT_THREADSAFE_USE_GETGRNAM_R
#define getgrent() UNSAFE_GETGRENT_NOT_THREADSAFE_USE_GETGRENT_R
#define getgrgid(a) UNSAFE_GETGRGID_NOT_THREADSAFE_USE_GETGRGID_R
#define fgetgrent() UNSAFE_FGETGRENT_NOT_THREADSAFE_USE_FGETGRGID_R
#define fcvt(a,b,c,d) UNSAFE_FCVT_NOT_THREADSAFE_AND_DEPRECATED
#define ecvt(a,b,c,d) UNSAFE_ECVT_NOT_THREADSAFE_AND_DEPRECATED
#define gcvt(a,b,c) UNSAFE_GCVT_NOT_THREADSAFE_AND_DEPRECATED
#define strptime(a,b,c) STRPTIME_NOT_EXISTS_ON_SOME_DM500_DB2()
#define ftime(a) FTIME_DEPRECATED()
#define timegm(a) TIMEGM_GNU_SPECIFIC_USE_CS_TIMEGM
#endif
#ifdef UNUSED
#elif __GNUC__ >= 3 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)
# define UNUSED(x) UNUSED_ ## x __attribute__((unused))
#elif defined(__LCLINT__)
# define UNUSED(x) /*@unused@*/ x
#else
# define UNUSED(x) x
#endif
#if __GNUC__ >= 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
# define MUST_CHECK_RESULT __attribute__((warn_unused_result))
#endif
#ifdef OK
#undef OK
#endif
#ifdef ERROR
#undef ERROR
#endif
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#ifdef WITH_DEBUG
# define call(arg) \
if(arg) \
{ \
cs_log_dbg(D_TRACE, "ERROR, function call %s returns error.",#arg); \
return ERROR; \
}
#else
# define call(arg) \
if(arg) \
{ \
return ERROR; \
}
#endif
// checking if (X) free(X) unneccessary since freeing a null pointer doesnt do anything
#define NULLFREE(X) {if (X) {void *tmpX=X; X=NULL; free(tmpX); }}
#ifdef __CYGWIN__
#define cs_recv(a,b,c,d) cygwin_recv(a,b,c,d)
#else
#define cs_recv(a,b,c,d) recv(a,b,c,d)
#endif
// safe wrappers to pthread functions
#define fprintf_stderr(fmt, params...) fprintf(stderr, fmt, ##params)
#define SAFE_PTHREAD_1ARG(a, b, c) { \
int32_t pter = a(b); \
if(pter != 0) \
{ \
c("FATAL ERROR: %s() failed in %s with error %d %s\n", #a, __func__, pter, strerror(pter)); \
} }
#define SAFE_MUTEX_LOCK(a) SAFE_PTHREAD_1ARG(pthread_mutex_lock, a, cs_log)
#define SAFE_MUTEX_UNLOCK(a) SAFE_PTHREAD_1ARG(pthread_mutex_unlock, a, cs_log)
#define SAFE_COND_SIGNAL(a) SAFE_PTHREAD_1ARG(pthread_cond_signal, a, cs_log)
#define SAFE_COND_BROADCAST(a) SAFE_PTHREAD_1ARG(pthread_cond_broadcast, a, cs_log)
#define SAFE_RWLOCK_RDLOCK(a) SAFE_PTHREAD_1ARG(pthread_rwlock_rdlock, a, cs_log)
#define SAFE_RWLOCK_WRLOCK(a) SAFE_PTHREAD_1ARG(pthread_rwlock_wrlock, a, cs_log)
#define SAFE_RWLOCK_UNLOCK(a) SAFE_PTHREAD_1ARG(pthread_rwlock_unlock, a, cs_log)
#define SAFE_ATTR_INIT(a) SAFE_PTHREAD_1ARG(pthread_attr_init, a, cs_log)
#define SAFE_MUTEXATTR_INIT(a) SAFE_PTHREAD_1ARG(pthread_mutexattr_init, a, cs_log)
#define SAFE_CONDATTR_INIT(a) SAFE_PTHREAD_1ARG(pthread_condattr_init, a, cs_log)
#define SAFE_MUTEX_LOCK_NOLOG(a) SAFE_PTHREAD_1ARG(pthread_mutex_lock, a, fprintf_stderr)
#define SAFE_MUTEX_UNLOCK_NOLOG(a) SAFE_PTHREAD_1ARG(pthread_mutex_unlock, a, fprintf_stderr)
#define SAFE_COND_SIGNAL_NOLOG(a) SAFE_PTHREAD_1ARG(pthread_cond_signal, a, fprintf_stderr)
#define SAFE_MUTEX_UNLOCK_NOLOG(a) SAFE_PTHREAD_1ARG(pthread_mutex_unlock, a, fprintf_stderr)
#define SAFE_ATTR_INIT_NOLOG(a) SAFE_PTHREAD_1ARG(pthread_attr_init, a, fprintf_stderr)
#define SAFE_CONDATTR_INIT_NOLOG(a) SAFE_PTHREAD_1ARG(pthread_condattr_init, a, fprintf_stderr)
#define SAFE_PTHREAD_2ARG(a, b, c, d) { \
int32_t pter = a(b, c); \
if(pter != 0) \
{ \
d("FATAL ERROR: %s() failed in %s with error %d %s\n", #a, __func__, pter, strerror(pter)); \
} }
#define SAFE_COND_WAIT(a,b) SAFE_PTHREAD_2ARG(pthread_cond_wait, a, b, cs_log)
#define SAFE_THREAD_JOIN(a,b) SAFE_PTHREAD_2ARG(pthread_join, a, b, cs_log)
#define SAFE_SETSPECIFIC(a,b) SAFE_PTHREAD_2ARG(pthread_setspecific, a, b, cs_log)
#define SAFE_MUTEXATTR_SETTYPE(a,b) SAFE_PTHREAD_2ARG(pthread_mutexattr_settype, a, b, cs_log)
#define SAFE_MUTEX_INIT(a,b) SAFE_PTHREAD_2ARG(pthread_mutex_init, a, b, cs_log)
#define SAFE_COND_INIT(a,b) SAFE_PTHREAD_2ARG(pthread_cond_init, a, b, cs_log)
#define SAFE_CONDATTR_SETCLOCK(a,b) SAFE_PTHREAD_2ARG(pthread_condattr_setclock, a, b, cs_log)
#define SAFE_MUTEX_INIT_NOLOG(a,b) SAFE_PTHREAD_2ARG(pthread_mutex_init, a, b, fprintf_stderr)
#define SAFE_COND_INIT_NOLOG(a,b) SAFE_PTHREAD_2ARG(pthread_cond_init, a, b, fprintf_stderr)
#define SAFE_THREAD_JOIN_NOLOG(a,b) SAFE_PTHREAD_2ARG(pthread_join, a, b, fprintf_stderr)
#define SAFE_CONDATTR_SETCLOCK_NOLOG(a,b) SAFE_PTHREAD_2ARG(pthread_condattr_setclock, a, b, fprintf_stderr)
#define SAFE_PTHREAD_1ARG_R(a, b, c, d) { \
int32_t pter = a(b); \
if(pter != 0) \
{ \
c("FATAL ERROR: %s() failed in %s (called from %s) with error %d %s\n", #a, __func__, d, pter, strerror(pter)); \
} }
#define SAFE_MUTEX_LOCK_R(a, b) SAFE_PTHREAD_1ARG_R(pthread_mutex_lock, a, cs_log, b)
#define SAFE_MUTEX_UNLOCK_R(a, b) SAFE_PTHREAD_1ARG_R(pthread_mutex_unlock, a, cs_log, b)
#define SAFE_COND_SIGNAL_R(a, b) SAFE_PTHREAD_1ARG_R(pthread_cond_signal, a, cs_log, b)
#define SAFE_COND_BROADCAST_R(a, b) SAFE_PTHREAD_1ARG_R(pthread_cond_broadcast, a, cs_log, b)
#define SAFE_CONDATTR_INIT_R(a, b) SAFE_PTHREAD_1ARG_R(pthread_condattr_init, a, cs_log, b)
#define SAFE_MUTEX_LOCK_NOLOG_R(a, b) SAFE_PTHREAD_1ARG_R(pthread_mutex_lock, a, fprintf_stderr, b)
#define SAFE_MUTEX_UNLOCK_NOLOG_R(a, b) SAFE_PTHREAD_1ARG_R(pthread_mutex_unlock, a, fprintf_stderr, b)
#define SAFE_CONDATTR_INIT_NOLOG_R(a, b) SAFE_PTHREAD_1ARG_R(pthread_condattr_init, a, fprintf_stderr, b)
#define SAFE_PTHREAD_2ARG_R(a, b, c, d, e) { \
int32_t pter = a(b, c); \
if(pter != 0) \
{ \
d("FATAL ERROR: %s() failed in %s (called from %s) with error %d %s\n", #a, __func__, e, pter, strerror(pter)); \
} }
#define SAFE_MUTEX_INIT_R(a,b,c) SAFE_PTHREAD_2ARG_R(pthread_mutex_init, a, b, cs_log, c)
#define SAFE_COND_INIT_R(a,b,c) SAFE_PTHREAD_2ARG_R(pthread_cond_init, a, b, cs_log, c)
#define SAFE_CONDATTR_SETCLOCK_R(a,b,c) SAFE_PTHREAD_2ARG(pthread_condattr_setclock, a, b, cs_log, c)
#define SAFE_MUTEX_INIT_NOLOG_R(a,b,c) SAFE_PTHREAD_2ARG_R(pthread_mutex_init, a, b, fprintf_stderr, c)
#define SAFE_COND_INIT_NOLOG_R(a,b,c) SAFE_PTHREAD_2ARG_R(pthread_cond_init, a, b, fprintf_stderr, c)
#define SAFE_CONDATTR_SETCLOCK_NOLOG_R(a,b,c) SAFE_PTHREAD_2ARG(pthread_condattr_setclock, a, b, fprintf_stderr, c)
#define SAFE_COND_TIMEDWAIT(a, b, c) { \
int32_t pter; \
if((c)->tv_nsec < 0) (c)->tv_nsec = 0; \
if((c)->tv_nsec > 999999999) (c)->tv_nsec = 999999999; \
pter = pthread_cond_timedwait(a, b, c); \
if(pter != 0 && pter != ETIMEDOUT) \
{ \
cs_log("FATAL ERROR: pthread_cond_timedwait failed in %s with error %d %s\n", __func__, pter, strerror(pter)); \
} }
#define SAFE_COND_TIMEDWAIT_R(a, b, c, d) { \
int32_t pter; \
if((c)->tv_nsec < 0) (c)->tv_nsec = 0; \
if((c)->tv_nsec > 999999999) (c)->tv_nsec = 999999999; \
pter = pthread_cond_timedwait(a, b, c); \
if(pter != 0 && pter != ETIMEDOUT) \
{ \
cs_log("FATAL ERROR: pthread_cond_timedwait failed in %s (called from %s) with error %d %s\n", __func__, d, pter, strerror(pter)); \
} }
#define SAFE_ATTR_SETSTACKSIZE(a,b) { \
int32_t pter = pthread_attr_setstacksize(a, b); \
if(pter != 0) \
{ \
cs_log("WARNING: pthread_attr_setstacksize() failed in %s with error %d %s\n", __func__, pter, strerror(pter)); \
} }
#define SAFE_ATTR_SETSTACKSIZE_NOLOG(a,b) { \
int32_t pter = pthread_attr_setstacksize(a, b); \
if(pter != 0) \
{ \
fprintf_stderr("WARNING: pthread_attr_setstacksize() failed in %s with error %d %s\n", __func__, pter, strerror(pter)); \
} }
#ifdef NO_PTHREAD_STACKSIZE
#undef SAFE_ATTR_SETSTACKSIZE
#undef SAFE_ATTR_SETSTACKSIZE_NOLOG
#define SAFE_ATTR_SETSTACKSIZE(a,b)
#define SAFE_ATTR_SETSTACKSIZE_NOLOG(a,b)
#endif
#define CHECK_BIT(var,pos) (((var) & (1<<(pos)))? 1 : 0)
/* ===========================
* constants
* =========================== */
#define SCM_URL "https://github.com/oscam-emu/oscam-patched"
#define WIKI_URL "https://wiki.streamboard.tv/wiki"
#define BOARD_URL "https://board.streamboard.tv"
#ifndef CS_VERSION
#define CS_VERSION "2.24.09-11825"
#endif
#ifndef CS_GIT_COMMIT
#define CS_GIT_COMMIT "a2b4c6d8"
#endif
#ifdef CS_CACHEEX
#ifdef CS_CACHEEX_AIO
#define CS_AIO_VERSION CS_VERSION
#endif
#endif
#ifndef CS_TARGET
# define CS_TARGET "unknown"
#endif
#ifndef CS_CONFDIR
#define CS_CONFDIR "/usr/local/etc"
#endif
#ifndef CS_LOGFILE
#define CS_LOGFILE "/var/log/oscam.log"
#endif
#define CS_QLEN 128 // size of request queue
#define CS_MAXPROV 32
#define CS_MAXPORTS 32 // max server ports
#define CS_CLIENT_HASHBUCKETS 32
#define CS_SERVICENAME_SIZE 32
#define CS_ECMSTORESIZE 16 // use MD5()
#define CS_EMMSTORESIZE 16 // use MD5()
#define CS_CLIENT_TIMEOUT 5000
#define CS_CLIENT_MAXIDLE 120
#define CS_BIND_TIMEOUT 120
#define CS_DELAY 0
#define CS_ECM_RINGBUFFER_MAX 0x10 // max size for ECM last responsetimes ringbuffer. Keep this set to power of 2 values!
// Support for multiple CWs per channel and other encryption algos
#define WITH_EXTENDED_CW 1
#define MAX_ECM_SIZE 1024
#define MAX_EMM_SIZE 1024
#define MAX_CMD_SIZE 0xff + 5 // maximum value from length byte + command header
#ifdef WITH_EMU
#define CS_EMMCACHESIZE 1024 // nr of EMMs that EMU reader will cache
#else
#define CS_EMMCACHESIZE 512 // nr of EMMs that each reader will cache
#endif
#define MSGLOGSIZE 64 // size of string buffer for a ecm to return messages
#define D_TRACE 0x0001 // Generate very detailed error/trace messages per routine
#define D_ATR 0x0002 // Debug ATR parsing, dump of ecm, cw
#define D_READER 0x0004 // Debug Reader/Proxy Process
#define D_CLIENT 0x0008 // Debug Client Process
#define D_IFD 0x0010 // Debug IFD+protocol
#define D_DEVICE 0x0020 // Debug Reader I/O
#define D_EMM 0x0040 // Dumps EMM
#define D_DVBAPI 0x0080 // Debug DVBAPI
#define D_LB 0x0100 // Debug Loadbalancer/ECM handler
#define D_CACHEEX 0x0200 // Debug CACHEEX
#define D_CLIENTECM 0x0400 // Debug Client ECMs
#define D_CSP 0x0800 // Debug CSP
#define D_CWC 0x1000 // Debug CWC
#ifdef CS_CACHEEX_AIO
#define D_CW_CACHE 0x2000 // Debug CW Cache
#endif
#define D_ALL_DUMP 0xFFFF // dumps all
#ifdef CS_CACHEEX_AIO
#define MAX_DEBUG_LEVELS 14
#else
#define MAX_DEBUG_LEVELS 13
#endif
/////// phoenix readers which need baudrate setting and timings need to be guarded by OSCam: BEFORE R_MOUSE
#define R_DB2COM1 0x1 // Reader Dbox2 @ com1
#define R_DB2COM2 0x2 // Reader Dbox2 @ com1
#define R_SC8in1 0x3 // Reader Sc8in1 or MCR
#define R_MP35 0x4 // AD-Teknik Multiprogrammer 3.5 and 3.6 (only usb tested)
#define R_MOUSE 0x5 // Reader smartcard mouse
/////// internal readers (Dreambox, Coolstream, IPBox) are all R_INTERNAL, they are determined compile-time
#define R_INTERNAL 0x6 // Reader smartcard intern
/////// readers that do not reed baudrate setting and timings are guarded by reader itself (large buffer built in): AFTER R_SMART
#define R_SMART 0x7 // Smartreader+
#define R_PCSC 0x8 // PCSC
#define R_DRECAS 0x9 // Reader DRECAS
#define R_EMU 0x17 // Reader EMU
/////// proxy readers after R_CS378X
#define R_CAMD35 0x20 // Reader cascading camd 3.5x
#define R_CAMD33 0x21 // Reader cascading camd 3.3x
#define R_NEWCAMD 0x22 // Reader cascading newcamd
#define R_RADEGAST 0x23 // Reader cascading radegast
#define R_CS378X 0x24 // Reader cascading camd 3.5x TCP
#define R_CONSTCW 0x25 // Reader for Constant CW
#define R_CSP 0x26 // Cache CSP
#define R_GHTTP 0x27 // Reader ghttp
#define R_SCAM 0x28 // Reader cascading scam
/////// peer to peer proxy readers after R_CCCAM
#define R_GBOX 0x30 // Reader cascading gbox
#define R_CCCAM 0x35 // Reader cascading cccam
#define R_PANDORA 0x36 // Reader cascading pandora
#define R_SERIAL 0x80 // Reader serial
#define R_IS_NETWORK 0x60
#define R_IS_CASCADING 0xE0
#define is_network_reader(__X) (__X->typ & R_IS_NETWORK)
#define is_cascading_reader(__X) (__X->typ & R_IS_CASCADING)
#define is_smargo_reader(__X) (__X->crdr && strcmp(__X->crdr->desc, "smargo") == 0)
// ECM rc codes:
/////// all found
#define E_FOUND 0
#define E_CACHE1 1
#define E_CACHE2 2
#define E_CACHEEX 3
/////// all notfound, some error or problem
#define E_NOTFOUND 4 // for selection of found, use < E_NOTFOUND
#define E_TIMEOUT 5
#define E_SLEEPING 6
#define E_FAKE 7
#define E_INVALID 8
#define E_CORRUPT 9
#define E_NOCARD 10
#define E_EXPDATE 11
#define E_DISABLED 12
#define E_STOPPED 13 // for selection of error, use <= E_STOPPED and exclude selection of found
#define E_ALREADY_SENT 101
#define E_WAITING 102
#define E_99 99 // this code is undocumented
#define E_UNHANDLED 100 // for selection of unhandled, use >= E_UNHANDLED
#define CS_MAX_MOD 20
#define MOD_CONN_TCP 1
#define MOD_CONN_UDP 2
#define MOD_CONN_NET 3
#define MOD_CONN_SERIAL 4
#define MOD_NO_CONN 8
#define EMM_UNIQUE 1
#define EMM_SHARED 2
#define EMM_GLOBAL 4
#define EMM_UNKNOWN 8
// Listener Types
#define LIS_CAMD33TCP 1
#define LIS_CAMD35UDP 2
#define LIS_CAMD35TCP 4
#define LIS_NEWCAMD 8
#define LIS_CCCAM 16
#define LIS_GBOX 32
#define LIS_RADEGAST 64
#define LIS_DVBAPI 128
#define LIS_CONSTCW 256
#define LIS_SERIAL 1024
#define LIS_CSPUDP 2048
#define LIS_SCAM 4096
// EMM types:
#define UNKNOWN 0
#define UNIQUE 1
#define SHARED 2
#define GLOBAL 3
#define NCD_AUTO 0
#define NCD_524 1
#define NCD_525 2
// moved from reader-common.h
#define UNKNOWN 0
#define CARD_NEED_INIT 1
#define CARD_INSERTED 2
#define CARD_FAILURE 3
#define NO_CARD 4
#define READER_DEVICE_ERROR 5
// moved from stats
#define DEFAULT_REOPEN_SECONDS 30
#define DEFAULT_MIN_ECM_COUNT 5
#define DEFAULT_MAX_ECM_COUNT 500
#define DEFAULT_NBEST 1
#define DEFAULT_NFB 1
#define DEFAULT_RETRYLIMIT 0
#define DEFAULT_LB_MODE 0
#define DEFAULT_LB_STAT_CLEANUP 336
#define DEFAULT_UPDATEINTERVAL 240
#define DEFAULT_LB_AUTO_BETATUNNEL 1
#define DEFAULT_LB_AUTO_BETATUNNEL_MODE 0
#define DEFAULT_LB_AUTO_BETATUNNEL_PREFER_BETA 50
#define DEFAULT_MAX_CACHE_TIME 15
#define DEFAULT_MAX_HITCACHE_TIME 15
#define DEFAULT_LB_AUTO_TIMEOUT 0
#define DEFAULT_LB_AUTO_TIMEOUT_P 30
#define DEFAULT_LB_AUTO_TIMEOUT_T 300
enum {E1_GLOBAL = 0, E1_USER, E1_READER, E1_SERVER, E1_LSERVER};
// LB blocking events:
enum {E2_GLOBAL = 0, E2_GROUP, E2_CAID, E2_IDENT, E2_CLASS, E2_CHID, E2_QUEUE, E2_OFFLINE,
E2_SID, E2_CCCAM_NOCARD,
// From here only LB nonblocking events:
E2_CCCAM_NOK1, E2_CCCAM_NOK2, E2_CCCAM_LOOP, E2_WRONG_CHKSUM, E2_RATELIMIT
};
#define LB_NONBLOCK_E2_FIRST E2_CCCAM_NOK1
#define CTA_RES_LEN 512
#define MAX_ATR_LEN 33 // max. ATR length
#define MAX_HIST 15 // max. number of historical characters
#define MAX_SIDBITS 64 // max services
#define SIDTABBITS uint64_t // 64bit type for services, if a system does not support this type,
// please use a define and define it as uint32_t / MAX_SIDBITS 32
#define BAN_UNKNOWN 1 // Failban mask for anonymous/ unknown contact
#define BAN_DISABLED 2 // Failban mask for Disabled user
#define BAN_SLEEPING 4 // Failban mask for sleeping user
#define BAN_DUPLICATE 8 // Failban mask for duplicate user
#define MAX_HTTP_DYNDNS 3 // maximum allowed Dyndns addresses for webif access
#define CHECK_WAKEUP 1
#define CHECK_ANTICASCADER 2
#define CHECK_ECMCACHE 3
#define AVAIL_CHECK_CONNECTED 0
#define AVAIL_CHECK_LOADBALANCE 1
#define ECM_FMT_LEN 109 // 64
#define CXM_FMT_LEN 209 // 160
#define LB_MAX_STAT_TIME 10
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__)
#define OSCAM_SIGNAL_WAKEUP SIGCONT
#else
#define OSCAM_SIGNAL_WAKEUP SIGRTMAX-2
#endif
#define READER_ACTIVE 0x01
#define READER_FALLBACK 0x02
#define READER_LOCAL 0x04
#define READER_CACHEEX 0x08
#define REQUEST_SENT 0x10
#define REQUEST_ANSWERED 0x20
#define CW_MODE_ONE_CW 0
#define CW_MODE_MULTIPLE_CW 1
#define CW_TYPE_VIDEO 0
#define CW_TYPE_AUDIO 1
#define CW_TYPE_DATA 2
#define CW_ALGO_CSA 0
#define CW_ALGO_DES 1
#define CW_ALGO_AES128 2
#define CW_ALGO_CSA_ALT 3
#define CW_ALGO_MODE_ECB 0
#define CW_ALGO_MODE_CBC 1
#define SIZE_SHORTDAY 8
#define MAXALLOWEDTF 1001 // 10 allowed time frame slots for everyday + all [(3 + 1 + 10*(12) + 1)*8]
extern const char *shortDay[SIZE_SHORTDAY];
extern const char *weekdstr;
/* ===========================
* Default Values
* =========================== */
#define DEFAULT_INACTIVITYTIMEOUT 0
#define DEFAULT_TCP_RECONNECT_TIMEOUT 30
#define DEFAULT_NCD_KEEPALIVE 0
#define DEFAULT_CC_MAXHOPS 10
#define DEFAULT_CC_RESHARE -1 // Use global cfg
#define DEFAULT_CC_IGNRSHR -1 // Use global cfg
#define DEFAULT_CC_STEALTH -1 // Use global cfg
#define DEFAULT_CC_KEEPALIVE 0
#define DEFAULT_CC_RECONNECT 12000
#define DEFAULT_CC_RECV_TIMEOUT 2000
#define DEFAULT_AC_USERS -1 // Use global cfg
#define DEFAULT_AC_PENALTY -1 // Use global cfg
// Return MPEG section length
#define SCT_LEN(sct) (3+((sct[1]&0x0f)<<8)+sct[2])
// Used by readers
#define MAX_LEN 256
#define NO_CAID_VALUE 0xfffe
#define NO_PROVID_VALUE 0xfffffe
#define NO_SRVID_VALUE 0xfffe
// If NULL return empty string
#define ESTR(x) ((x) ? (x) : "")
#ifndef MAX
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#endif
#ifndef MIN
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#endif
/*
See: http://stackoverflow.com/questions/10269685/kernels-container-of-any-way-to-make-it-iso-conforming
http://www.kroah.com/log/linux/container_of.html
*/
#define container_of(ptr, type, member) \
((type *) ((char *) (ptr) - offsetof(type, member) + \
(&((type *) 0)->member == (ptr)) * 0))
/* ===========================
* global structures
* =========================== */
struct timeb
{
time_t time;
int64_t millitm;
};
typedef struct cs_mutexlock
{
int32_t timeout;
pthread_mutex_t lock;
pthread_cond_t writecond, readcond;
const char *name;
int8_t flag;
int16_t writelock, readlock;
} CS_MUTEX_LOCK;
#include "oscam-llist.h"
typedef struct s_caidvaluetab_data
{
uint16_t caid;
uint16_t value;
} CAIDVALUETAB_DATA;
typedef struct s_caidvaluetab
{
int32_t cvnum;
CAIDVALUETAB_DATA *cvdata;
} CAIDVALUETAB;
typedef struct s_classtab
{
uint8_t an;
uint8_t bn;
uint8_t *aclass;
uint8_t *bclass;
} CLASSTAB;
typedef struct s_caidtab_data
{
uint16_t caid;
uint16_t mask;
uint16_t cmap;
} CAIDTAB_DATA;
typedef struct s_caidtab
{
int32_t ctnum;
CAIDTAB_DATA *ctdata;
} CAIDTAB;
typedef struct s_tuntab_data
{
uint16_t bt_caidfrom;
uint16_t bt_caidto;
uint16_t bt_srvid;
} TUNTAB_DATA;
typedef struct s_tuntab
{
int32_t ttnum;
TUNTAB_DATA *ttdata;
} TUNTAB;
typedef struct s_sidtab
{
char label[64];
#ifdef CS_CACHEEX_AIO
uint8_t disablecrccws_only_for_exception;
uint8_t no_wait_time;
uint8_t lg_only_exception;
#endif
uint16_t num_caid;
uint16_t num_provid;
uint16_t num_srvid;
uint16_t *caid;
uint32_t *provid;
uint16_t *srvid;
struct s_sidtab *next;
} SIDTAB;
typedef struct s_filter
{
uint16_t caid;
uint8_t nprids;
uint32_t prids[CS_MAXPROV];
} FILTER;
typedef struct s_ftab
{
int32_t nfilts;
FILTER *filts;
} FTAB;
typedef struct s_ncd_ftab
{
int32_t nfilts;
FILTER filts[16];
} NCD_FTAB;
struct ncd_port
{
bool ncd_key_is_set;
uint8_t ncd_key[14];
NCD_FTAB ncd_ftab;
};
typedef struct s_port
{
int32_t fd;
int32_t s_port;
struct ncd_port *ncd; // newcamd specific settings
} PORT;
typedef struct s_ptab
{
int32_t nports;
PORT ports[CS_MAXPORTS];
} PTAB;
typedef struct aes_entry
{
uint16_t keyid;
uint16_t caid;
uint32_t ident;
uint8_t plainkey[16];
AES_KEY key;
struct aes_entry *next;
} AES_ENTRY;
struct aes_keys
{
AES_KEY aeskey_encrypt; // encryption key needed by monitor and used by camd33, camd35
AES_KEY aeskey_decrypt; // decryption key needed by monitor and used by camd33, camd35
};
struct s_ecm
{
uint8_t ecmd5[CS_ECMSTORESIZE];
uint8_t cw[16];
uint16_t caid;
uint64_t grp;
struct s_reader *reader;
int32_t rc;
time_t time;
};
struct s_emmstat
{
uint8_t emmd5[CS_EMMSTORESIZE];
uint8_t type;
int32_t count;
struct timeb firstwritten;
struct timeb lastwritten;
};
struct s_emmcache
{
uint8_t emmd5[CS_EMMSTORESIZE];
uint8_t type;
uint16_t len;
uint8_t emm[MAX_EMM_SIZE];
struct timeb firstseen;
struct timeb lastseen;
};
struct s_csystem_emm_filter
{
uint8_t type;
uint8_t enabled;
uint8_t filter[16];
uint8_t mask[16];
};
typedef struct v_ban // Failban listmember
{
int32_t v_count;
IN_ADDR_T v_ip;
int32_t v_port;
struct timeb v_time;
bool acosc_entry;
int32_t acosc_penalty_dur;
char *info;
} V_BAN;
typedef struct s_cacheex_stat_entry // Cacheex stats listmember
{
int32_t cache_count;
time_t cache_last;
uint16_t cache_caid;
uint16_t cache_srvid;
uint32_t cache_prid;
int8_t cache_direction; // 0 = push / 1 = got
#ifdef CS_CACHEEX_AIO
int32_t cache_count_lg;
#endif
} S_CACHEEX_STAT_ENTRY;
typedef struct s_entitlement // contains entitlement Info
{
uint64_t id; // the element ID
uint32_t type; // enumerator for tier,chid whatever
// 0="", 1="Package", 2="PPV-Event", 3="chid", 4="tier", 5 = "class", 6 = "PBM". 7 = "seca-admin"
uint16_t caid; // the caid of element
uint32_t provid; // the provid of element
uint32_t class; // the class needed for some systems
time_t start; // startdate
time_t end; // enddate
#ifdef WITH_EMU
bool isKey;
bool isData;
char name[8];
uint8_t *key;
uint32_t keyLength;
#endif
} S_ENTITLEMENT;
struct s_client;
struct ecm_request_t;
struct emm_packet_t;
struct cmd_packet_t;
struct s_ecm_answer;
struct demux_s;
#define DEFAULT_MODULE_BUFSIZE 1024
struct s_module
{
const char *desc;
int8_t type;
int8_t large_ecm_support;
int16_t listenertype;
//int32_t s_port;
IN_ADDR_T s_ip;
uint16_t bufsize;
void *(*s_handler)(struct s_client *, uint8_t *, int32_t);
void (*s_init)(struct s_client *);
int32_t (*recv)(struct s_client *, uint8_t *, int32_t);
void (*send_dcw)(struct s_client *, struct ecm_request_t *);
void (*cleanup)(struct s_client *);
int32_t (*c_recv_chk)(struct s_client *, uint8_t *, int32_t *, uint8_t *, int32_t);
int32_t (*c_init)(struct s_client *);
int32_t (*c_send_ecm)(struct s_client *, struct ecm_request_t *);
int32_t (*c_send_emm)(struct emm_packet_t *);
int32_t (*c_available)(struct s_reader *, int32_t, struct ecm_request_t *); // Schlocke: available check for load-balancing,
// params:
// rdr (reader to check)
// int32_t checktype (0=return connected, 1=return loadbalance-avail) return int
void (*c_idle)(void); // Schlocke: called when reader is idle
void (*s_idle)(struct s_client *);
void (*s_peer_idle)(struct s_client *);
void (*c_card_info)(void); // Schlocke: request card infos
int32_t (*c_capmt)(struct s_client *, struct demux_s *);
#ifdef CS_CACHEEX
int32_t (*c_cache_push)(struct s_client *, struct ecm_request_t *); // Cache push
int32_t (*c_cache_push_chk)(struct s_client *, struct ecm_request_t *); // Cache push Node Check, 0=no push
#endif
int32_t c_port;
PTAB ptab;
int32_t num;
};
struct s_ATR;
struct s_cardreader_settings
{
uint32_t ETU;
uint32_t EGT;
uint8_t P;
uint32_t I;
uint32_t F;
uint32_t Fi;
uint8_t Di;
uint8_t Ni;
uint32_t WWT;
uint32_t BGT;
uint8_t D;
};
struct s_cardreader
{
const char *desc;
int32_t (*reader_init)(struct s_reader *);
int32_t (*get_status)(struct s_reader *, int *);
int32_t (*activate)(struct s_reader *, struct s_ATR *);
int32_t (*transmit)(struct s_reader *, uint8_t *sent, uint32_t size, uint32_t expectedlen, uint32_t delay, uint32_t timeout);
int32_t (*receive)(struct s_reader *, uint8_t *data, uint32_t size, uint32_t delay, uint32_t timeout);
int32_t (*lock_init)(struct s_reader *);
void (*lock)(struct s_reader *);
void (*unlock)(struct s_reader *);
int32_t (*close)(struct s_reader *);
int32_t (*set_parity)(struct s_reader *, uint8_t parity);
int32_t (*write_settings)(struct s_reader *, struct s_cardreader_settings *s);
int32_t (*set_protocol)(struct s_reader *, uint8_t *params, uint32_t *length, uint32_t len_request);
int32_t (*set_baudrate)(struct s_reader *, uint32_t baud); // set only for readers which need baudrate setting and timings need to be guarded by OSCam
int32_t (*card_write)(struct s_reader *pcsc_reader, const uint8_t *buf, uint8_t *cta_res, uint16_t *cta_lr, int32_t l);
void (*display_msg)(struct s_reader *, char *msg);
int32_t (*do_reset)(struct s_reader *, struct s_ATR *, int32_t (*rdr_activate_card)(struct s_reader *, struct s_ATR *, uint16_t deprecated), int32_t (*rdr_get_cardsystem)(struct s_reader *, struct s_ATR *));
bool (*set_DTS_RTS)(struct s_reader *, int32_t *dtr, int32_t *rts);
int32_t typ; // fixme: workaround, remove when all old code is converted
int8_t max_clock_speed; // 1 for reader->typ > R_MOUSE
int8_t need_inverse; // 0 = reader does inversing; 1 = inversing done by oscam
//io_serial config
int8_t flush;
int8_t read_written; // 1 = written bytes has to read from device
bool skip_extra_atr_parsing;