Timeout patch
[oscam.git] / oscam.c
blob0d08bb1a53c070875b86d88c6713b629960aaeac
1 #define CS_CORE
2 #include "globals.h"
3 #ifdef CS_WITH_GBOX
4 # include "csgbox/gbox.h"
5 # define CS_VERSION_X CS_VERSION "-gbx-" GBXVERSION
6 #else
7 # define CS_VERSION_X CS_VERSION
8 #endif
9 /*****************************************************************************
10 Globals
11 *****************************************************************************/
12 int pfd=0; // Primary FD, must be closed on exit
13 int mfdr=0; // Master FD (read)
14 int fd_m2c=0; // FD Master -> Client (for clients / read )
15 int fd_c2m=0; // FD Client -> Master (for clients / write )
16 int fd_c2l=0; // FD Client -> Logger (for clients / write )
17 int cs_dblevel=0; // Debug Level (TODO !!)
18 int cs_idx=0; // client index (0=master, ...)
19 int cs_ptyp=D_MASTER; // process-type
20 struct s_module ph[CS_MAX_MOD]; // Protocols
21 int maxph=0; // Protocols used
22 int cs_hw=0; // hardware autodetect
23 int is_server=0; // used in modules to specify function
24 int premhack=0; // used to activate premiere hack 1801 -> 1702
25 pid_t master_pid=0; // master pid OUTSIDE shm
26 ushort len4caid[256]; // table for guessing caid (by len)
27 char cs_confdir[128]=CS_CONFDIR;
28 uchar mbuf[1024]; // global buffer
29 ECM_REQUEST *ecmtask;
30 EMM_PACKET epg;
31 #ifdef CS_ANTICASC
32 struct s_acasc ac_stat[CS_MAXPID];
33 #endif
35 /*****************************************************************************
36 Shared Memory
37 *****************************************************************************/
38 int *ecmidx; // Shared Memory
39 int *logidx; // Shared Memory
40 int *oscam_sem; // sem (multicam.o)
41 int *c_start; // idx of 1st client
42 int *log_fd; // log-process is running
43 struct s_ecm *ecmcache; // Shared Memory
44 struct s_client *client; // Shared Memory
45 struct s_reader *reader; // Shared Memory
47 struct card_struct *Cards; // Shared Memory
48 struct idstore_struct *idstore; // Shared Memory
49 unsigned long *IgnoreList; // Shared Memory
51 struct s_config *cfg; // Shared Memory
52 #ifdef CS_ANTICASC
53 struct s_acasc_shm *acasc; // anti-cascading table indexed by account.ac_idx
54 #endif
55 #ifdef CS_LOGHISTORY
56 int *loghistidx; // ptr to current entry
57 char *loghist; // ptr of log-history
58 #endif
59 int *mcl=0; // Master close log?
61 static int shmsize = CS_ECMCACHESIZE*(sizeof(struct s_ecm)) +
62 CS_MAXPID*(sizeof(struct s_client)) +
63 CS_MAXREADER*(sizeof(struct s_reader)) +
64 #ifdef CS_WITH_GBOX
65 CS_MAXCARDS*(sizeof(struct card_struct))+
66 CS_MAXIGNORE*(sizeof(long))+
67 CS_MAXPID*(sizeof(struct idstore_struct))+
68 #endif
69 #ifdef CS_ANTICASC
70 CS_MAXPID*(sizeof(struct s_acasc_shm)) +
71 #endif
72 #ifdef CS_LOGHISTORY
73 CS_MAXLOGHIST*CS_LOGHISTSIZE + sizeof(int) +
74 #endif
75 sizeof(struct s_config)+(6*sizeof(int));
77 #ifdef CS_NOSHM
78 char cs_memfile[128]=CS_MMAPFILE;
79 #endif
81 /*****************************************************************************
82 Statics
83 *****************************************************************************/
84 static char mloc[128]={0};
85 static int shmid=0; // Shared Memory ID
86 static int cs_last_idx=0; // client index of last fork (master only)
87 static char* credit[] = {
88 "dukat for the great MpCS piece of code",
89 "all members of streamboard.de.vu for testing",
90 "scotty and aroureos for the first softcam (no longer used)",
91 "John Moore for the hsic-client (humax 5400) and the arm-support",
92 "doz21 for the sio-routines and his support on camd3-protocol",
93 "kindzadza for his support on radegast-protocol",
94 "DS and ago for several modules in mpcs development",
95 "dingo35 for seca reader-support",
96 "dingo35 and okmikel for newcamd-support",
97 "hellmaster1024 for gb*x-support",
98 "the vdr-sc team for several good ideas :-)",
99 NULL };
101 static void cs_set_mloc(int ato, char *txt)
103 if (ato>=0)
104 alarm(ato);
105 if (txt)
106 strcpy(mloc, txt);
109 char *cs_platform(char *buf)
111 static char *hw=NULL;
112 if (!hw)
114 #ifdef TUXBOX
115 struct stat st;
116 cs_hw=CS_HW_DBOX2; // dbox2, default for now
117 if (!stat("/dev/sci0", &st)) cs_hw=CS_HW_DREAM; // dreambox
118 switch(cs_hw)
120 #ifdef PPC
121 case CS_HW_DBOX2: hw="dbox2" ; break;
122 #endif
123 case CS_HW_DREAM: hw="dreambox"; break;
125 #endif
126 if (!hw) hw=CS_OS_HW;
128 sprintf(buf, "%s-%s-%s", CS_OS_CPU, hw, CS_OS_SYS);
129 return(buf);
132 static void usage()
134 int i;
135 fprintf(stderr, "\nOSCam cardserver v%s (%s) - (w) 2009 by smurzch\n", CS_VERSION_X, CS_OSTYPE);
136 fprintf(stderr, "\tbased on streamboard mp-cardserver v0.9d - (w) 2004-2007 by dukat\n\n");
137 fprintf(stderr, "oscam [-b] [-c config-dir]");
138 #ifdef CS_NOSHM
139 fprintf(stderr, " [-m memory-file]");
140 #endif
141 fprintf(stderr, "\n\n\t-b : start in background\n");
142 fprintf(stderr, "\t-c <dir> : read configuration from <dir>\n");
143 fprintf(stderr, "\t default=%s\n", CS_CONFDIR);
144 #ifdef CS_NOSHM
145 fprintf(stderr, "\t-m <file>: use <file> as mmaped memory file\n");
146 fprintf(stderr, "\t default=%s\n", CS_MMAPFILE);
147 #endif
148 fprintf(stderr, "\nthanks to ...\n");
149 for (i=0; credit[i]; i++)
150 fprintf(stderr, "\t%s\n", credit[i]);
151 fprintf(stderr, "\n");
152 exit(1);
155 #ifdef NEED_DAEMON
156 static int daemon(int nochdir, int noclose)
158 int fd;
160 switch (fork())
162 case -1: return (-1);
163 case 0: break;
164 default: _exit(0);
167 if (setsid()==(-1))
168 return(-1);
170 if (!nochdir)
171 (void)chdir("/");
173 if (!noclose && (fd=open("/dev/null", O_RDWR, 0)) != -1)
175 (void)dup2(fd, STDIN_FILENO);
176 (void)dup2(fd, STDOUT_FILENO);
177 (void)dup2(fd, STDERR_FILENO);
178 if (fd>2)
179 (void)close(fd);
181 return(0);
183 #endif
185 int recv_from_udpipe(uchar *buf, int l)
187 unsigned short n;
188 if (!pfd) return(-9);
189 read(pfd, buf, 3);
190 if (buf[0]!='U')
192 cs_log("INTERNAL PIPE-ERROR");
193 cs_exit(1);
195 memcpy(&n, buf+1, 2);
196 return(read(pfd, buf, n));
199 char *username(int idx)
201 if (client[idx].usr[0])
202 return(client[idx].usr);
203 else
204 return("anonymous");
207 static int idx_from_ip(in_addr_t ip, in_port_t port)
209 int i, idx;
210 for (i=idx=0; (i<CS_MAXPID) && (!idx); i++)
211 if ((client[i].ip==ip) && (client[i].port==port) &&
212 ((client[i].typ=='c') || (client[i].typ=='m')))
213 idx=i;
214 return(idx);
217 int idx_from_pid(pid_t pid)
219 int i, idx;
220 for (i=0, idx=(-1); (i<CS_MAXPID) && (idx<0); i++)
221 if (client[i].pid==pid)
222 idx=i;
223 return(idx);
226 static long chk_caid(ushort caid, CAIDTAB *ctab)
228 int n;
229 long rc;
230 for (rc=(-1), n=0; (n<CS_MAXCAIDTAB) && (rc<0); n++)
231 if ((caid & ctab->mask[n]) == ctab->caid[n])
232 rc=ctab->cmap[n] ? ctab->cmap[n] : caid;
233 return(rc);
236 int chk_bcaid(ECM_REQUEST *er, CAIDTAB *ctab)
238 long caid;
239 if ((caid=chk_caid(er->caid, ctab))<0)
240 return(0);
241 er->caid=caid;
242 return(1);
246 * void set_signal_handler(int sig, int flags, void (*sighandler)(int))
247 * flags: 1 = restart, 2 = don't modify if SIG_IGN, may be combined
249 void set_signal_handler(int sig, int flags, void (*sighandler)(int))
251 #ifdef CS_SIGBSD
252 if ((signal(sig, sighandler)==SIG_IGN) && (flags & 2))
254 signal(sig, SIG_IGN);
255 siginterrupt(sig, 0);
257 else
258 siginterrupt(sig, (flags & 1) ? 0 : 1);
259 #else
260 struct sigaction sa;
261 sigaction(sig, (struct sigaction *) 0, &sa);
262 if (!((flags & 2) && (sa.sa_handler==SIG_IGN)))
264 sigemptyset(&sa.sa_mask);
265 sa.sa_flags=(flags & 1) ? SA_RESTART : 0;
266 sa.sa_handler=sighandler;
267 sigaction(sig, &sa, (struct sigaction *) 0);
269 #endif
272 static void cs_alarm(int sig)
274 cs_debug("Got alarm signal");
275 cs_log("disconnect from %s (deadlock!)", cs_inet_ntoa(client[cs_idx].ip));
276 cs_exit(0);
279 static void cs_master_alarm(int sig)
281 cs_log("PANIC: master deadlock! last location: %s", mloc);
282 fprintf(stderr, "PANIC: master deadlock! last location: %s", mloc);
283 fflush(stderr);
284 cs_exit(0);
287 static void cs_sigpipe(int sig)
289 if ((cs_idx) && (master_pid!=getppid()))
290 cs_exit(0);
291 cs_log("Got sigpipe signal -> captured");
294 void cs_exit(int sig)
296 int i;
298 set_signal_handler(SIGCHLD, 1, SIG_IGN);
299 set_signal_handler(SIGHUP , 1, SIG_IGN);
300 if (sig && (sig!=SIGQUIT))
301 cs_log("exit with signal %d", sig);
302 switch(client[cs_idx].typ)
304 case 'c': cs_statistics(cs_idx);
305 case 'm': break;
306 case 'n': *log_fd=0;
307 break;
308 case 's': *log_fd=0;
309 for (i=1; i<CS_MAXPID; i++)
310 if (client[i].pid)
311 kill(client[i].pid, SIGQUIT);
312 cs_log("cardserver down");
313 #ifndef CS_NOSHM
314 if (ecmcache) shmdt((void *)ecmcache);
315 #endif
316 break;
318 if (pfd) close(pfd);
319 #ifdef CS_NOSHM
320 munmap((void *)ecmcache, (size_t)shmsize);
321 if (shmid) close(shmid);
322 unlink(CS_MMAPFILE); // ignore errors, last process must succeed
323 #endif
324 exit(sig);
327 static void cs_reinit_clients()
329 int i;
330 struct s_auth *account;
332 for( i=1; i<CS_MAXPID; i++ )
333 if( client[i].pid && client[i].typ=='c' && client[i].usr[0] )
335 for (account=cfg->account; (account) ; account=account->next)
336 if (!strcmp(client[i].usr, account->usr))
337 break;
339 if (account &&
340 client[i].pcrc==crc32(0L, MD5(account->pwd, strlen(account->pwd), NULL), 16))
342 client[i].grp = account->grp;
343 client[i].au = account->au;
344 client[i].tosleep = (60*account->tosleep);
345 client[i].monlvl = account->monlvl;
346 client[i].fchid = account->fchid; // CHID filters
347 client[i].cltab = account->cltab; // Class
348 client[i].ftab = account->ftab; // Ident
349 client[i].sidtabok= account->sidtabok; // services
350 client[i].sidtabno= account->sidtabno; // services
351 memcpy(&client[i].ctab, &account->ctab, sizeof(client[i].ctab));
352 #ifdef CS_ANTICASC
353 client[i].ac_idx = account->ac_idx;
354 client[i].ac_penalty = account->ac_penalty;
355 client[i].ac_limit = (account->ac_users*100+80)*cfg->ac_stime;
356 #endif
358 else
360 if (ph[client[i].ctyp].type & MOD_CONN_NET)
362 cs_debug("client '%s', pid=%d not found in db (or password changed)",
363 client[i].usr, client[i].pid);
364 kill(client[i].pid, SIGQUIT);
370 static void cs_sighup()
372 uchar dummy[1]={0x00};
373 write_to_pipe(fd_c2m, PIP_ID_HUP, dummy, 1);
376 static void cs_accounts_chk()
378 int i;
380 init_userdb();
381 cs_reinit_clients();
382 #ifdef CS_ANTICASC
383 for (i=0; i<CS_MAXPID; i++)
384 if (client[i].typ=='a')
386 kill(client[i].pid, SIGHUP);
387 break;
389 #endif
392 static void cs_debug_level()
394 int i;
396 cs_dblevel ^= D_ALL_DUMP;
397 if (master_pid==getpid())
398 for (i=0; i<CS_MAXPID && client[i].pid; i++)
399 client[i].dbglvl=cs_dblevel;
400 else
401 client[cs_idx].dbglvl=cs_dblevel;
402 cs_log("%sdebug_level=%d", (master_pid==getpid())?"all ":"",cs_dblevel);
405 static void cs_card_info(int i)
407 uchar dummy[1]={0x00};
408 for( i=1; i<CS_MAXPID; i++ )
409 if( client[i].pid && client[i].typ=='r' && client[i].fd_m2c )
410 write_to_pipe(client[i].fd_m2c, PIP_ID_CIN, dummy, 1);
412 //kill(client[i].pid, SIGUSR2);
415 static void cs_child_chk(int i)
417 while (waitpid(0, NULL, WNOHANG)>0);
418 for (i=1; i<CS_MAXPID; i++)
419 if (client[i].pid)
420 if (kill(client[i].pid, 0)) {
421 if ((client[i].typ!='c') && (client[i].typ!='m'))
423 char *txt="";
424 *log_fd=0;
425 switch(client[i].typ)
427 #ifdef CS_ANTICASC
428 case 'a': txt="anticascader"; break;
429 #endif
430 case 'l': txt="logger"; break;
431 case 'p': txt="proxy"; break;
432 case 'r': txt="reader"; break;
433 case 'n': txt="resolver"; break;
435 cs_log("PANIC: %s lost !! (pid=%d)", txt, client[i].pid);
436 cs_exit(1);
438 else
440 #ifdef CS_ANTICASC
441 char usr[32];
442 ushort ac_idx;
443 ushort ac_limit;
444 uchar ac_penalty;
445 if( cfg->ac_enabled )
447 strncpy(usr, client[i].usr, sizeof(usr)-1);
448 ac_idx = client[i].ac_idx;
449 ac_limit = client[i].ac_limit;
450 ac_penalty = client[i].ac_penalty;
452 #endif
453 if (client[i].fd_m2c) close(client[i].fd_m2c);
454 if (client[i].ufd) close(client[i].ufd);
455 memset(&client[i], 0, sizeof(struct s_client));
456 #ifdef CS_ANTICASC
457 if( cfg->ac_enabled )
459 client[i].ac_idx = ac_idx;
460 client[i].ac_limit = ac_limit;
461 client[i].ac_penalty = ac_penalty;
462 strcpy(client[i].usr, usr);
464 #endif
465 client[i].au=(-1);
468 return;
471 int cs_fork(in_addr_t ip, in_port_t port)
473 int i;
474 pid_t pid;
475 for (i=1; (i<CS_MAXPID) && (client[i].pid); i++);
476 if (i<CS_MAXPID)
478 int fdp[2];
479 memset(&client[i], 0, sizeof(struct s_client));
480 client[i].au=(-1);
481 if (pipe(fdp))
483 cs_log("Cannot create pipe (errno=%d)", errno);
484 cs_exit(1);
486 switch(pid=fork())
488 case -1:
489 cs_log("PANIC: Cannot fork() (errno=%d)", errno);
490 cs_exit(1);
491 case 0: // HERE is client
492 alarm(0);
493 set_signal_handler(SIGALRM, 0, cs_alarm);
494 set_signal_handler(SIGCHLD, 1, SIG_IGN);
495 set_signal_handler(SIGHUP , 1, SIG_IGN);
496 set_signal_handler(SIGINT , 1, SIG_IGN);
497 set_signal_handler(SIGUSR1, 1, cs_debug_level);
498 is_server=((ip) || (port<90)) ? 1 : 0;
499 fd_m2c=fdp[0];
500 close(fdp[1]);
501 close(mfdr);
502 if( port!=97 ) cs_close_log();
503 mfdr=0;
504 cs_ptyp=D_CLIENT;
505 cs_idx=i;
506 #ifndef CS_NOSHM
507 shmid=0;
508 #endif
509 break;
510 default: // HERE is master
511 client[i].fd_m2c=fdp[1];
512 client[i].dbglvl=cs_dblevel;
513 close(fdp[0]);
514 if (ip)
516 client[i].typ='c'; // dynamic client
517 client[i].ip=ip;
518 client[i].port=port;
519 cs_log("client(%d) connect from %s (pid=%d, pipfd=%d)",
520 i-cdiff, cs_inet_ntoa(ip), pid, client[i].fd_m2c);
522 else
524 client[i].stat=1;
525 switch(port)
527 case 99: client[i].typ='r'; // reader
528 client[i].sidtabok=reader[ridx].sidtabok;
529 client[i].sidtabno=reader[ridx].sidtabno;
530 reader[ridx].fd=client[i].fd_m2c;
531 reader[ridx].cs_idx=i;
532 if (reader[ridx].r_port)
533 cs_log("proxy started (pid=%d, server=%s)",
534 pid, reader[ridx].device);
535 else
537 if (reader[ridx].typ==R_MOUSE)
538 cs_log("reader started (pid=%d, device=%s, detect=%s%s, mhz=%d)",
539 pid, reader[ridx].device,
540 reader[ridx].detect&0x80 ? "!" : "",
541 RDR_CD_TXT[reader[ridx].detect&0x7f],
542 reader[ridx].mhz);
543 else
544 cs_log("reader started (pid=%d, device=%s)",
545 pid, reader[ridx].device);
546 client[i].ip=client[0].ip;
547 strcpy(client[i].usr, client[0].usr);
549 cdiff=i;
550 break;
551 case 98: client[i].typ='n'; // resolver
552 client[i].ip=client[0].ip;
553 strcpy(client[i].usr, client[0].usr);
554 cs_log("resolver started (pid=%d, delay=%d sec)",
555 pid, cfg->resolvedelay);
556 cdiff=i;
557 break;
558 case 97: client[i].typ='l'; // logger
559 client[i].ip=client[0].ip;
560 strcpy(client[i].usr, client[0].usr);
561 cs_log("logger started (pid=%d)", pid);
562 cdiff=i;
563 break;
564 #ifdef CS_ANTICASC
565 case 96: client[i].typ='a';
566 client[i].ip=client[0].ip;
567 strcpy(client[i].usr, client[0].usr);
568 cs_log("anticascader started (pid=%d, delay=%d min)",
569 pid, cfg->ac_stime);
570 cdiff=i;
571 break;
572 #endif
573 default: client[i].typ='c'; // static client
574 client[i].ip=client[0].ip;
575 client[i].ctyp=port;
576 cs_log("%s: initialized (pid=%d%s)", ph[port].desc,
577 pid, ph[port].logtxt ? ph[port].logtxt : "");
578 break;
581 client[i].login=client[i].last=time((time_t *)0);
582 client[i].pid=pid; // MUST be last -> wait4master()
583 cs_last_idx=i;
584 i=0;
587 else
589 cs_log("max connections reached -> reject client %s", cs_inet_ntoa(ip));
590 i=(-1);
592 return(i);
595 static void init_signal()
597 int i;
598 for (i=1; i<NSIG; i++)
599 set_signal_handler(i, 3, cs_exit);
600 set_signal_handler(SIGWINCH, 1, SIG_IGN);
601 // set_signal_handler(SIGPIPE , 0, SIG_IGN);
602 set_signal_handler(SIGPIPE , 0, cs_sigpipe);
603 // set_signal_handler(SIGALRM , 0, cs_alarm);
604 set_signal_handler(SIGALRM , 0, cs_master_alarm);
605 set_signal_handler(SIGCHLD , 1, cs_child_chk);
606 // set_signal_handler(SIGHUP , 1, cs_accounts_chk);
607 set_signal_handler(SIGHUP , 1, cs_sighup);
608 set_signal_handler(SIGUSR1, 1, cs_debug_level);
609 set_signal_handler(SIGUSR2, 1, cs_card_info);
610 set_signal_handler(SIGCONT, 1, SIG_IGN);
611 cs_log("signal handling initialized (type=%s)",
612 #ifdef CS_SIGBSD
613 "bsd"
614 #else
615 "sysv"
616 #endif
618 return;
621 static void init_shm()
623 #ifdef CS_NOSHM
624 //int i, fd;
625 char *buf;
626 if ((shmid=open(cs_memfile, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR))<0)
628 fprintf(stderr, "Cannot create mmaped file (errno=%d)", errno);
629 cs_exit(1);
632 buf=(char *)malloc(shmsize);
633 memset(buf, 0, shmsize);
634 write(shmid, buf, shmsize);
635 free(buf);
637 ecmcache=(struct s_ecm *)mmap((void *)0, (size_t) shmsize,
638 PROT_READ|PROT_WRITE, MAP_SHARED, shmid, 0);
639 #else
640 struct shmid_ds sd;
641 char *shmerr_txt="Cannot %s shared memory (errno=%d)\n";
642 if ((shmid=shmget(IPC_PRIVATE, shmsize, IPC_CREAT | 0600))<0)
644 fprintf(stderr, shmerr_txt, "create", errno);
645 shmid=0;
646 cs_exit(1);
648 if ((ecmcache=(struct s_ecm *)shmat(shmid, 0, 0))==(void *)(-1))
650 fprintf(stderr, shmerr_txt, "attach", errno);
651 cs_exit(1);
653 memset(ecmcache, 0, shmsize);
654 shmctl(shmid, IPC_RMID, &sd);
655 #endif
656 #ifdef CS_ANTICASC
657 acasc=(struct s_acasc_shm *)&ecmcache[CS_ECMCACHESIZE];
658 ecmidx=(int *)&acasc[CS_MAXPID];
659 #else
660 ecmidx=(int *)&ecmcache[CS_ECMCACHESIZE];
661 #endif
662 mcl=(int *)((void *)ecmidx+sizeof(int));
663 logidx=(int *)((void *)mcl+sizeof(int));
664 c_start=(int *)((void *)logidx+sizeof(int));
665 log_fd=(int *)((void *)c_start+sizeof(int));
666 oscam_sem=(int *)((void *)log_fd+sizeof(int));
667 client=(struct s_client *)((void *)oscam_sem+sizeof(int));
668 reader=(struct s_reader *)&client[CS_MAXPID];
669 #ifdef CS_WITH_GBOX
670 Cards=(struct card_struct*)&reader[CS_MAXREADER];
671 IgnoreList=(unsigned long*)&Cards[CS_MAXCARDS];
672 idstore=(struct idstore_struct*)&IgnoreList[CS_MAXIGNORE];
673 cfg=(struct s_config *)&idstore[CS_MAXPID];
674 #else
675 cfg=(struct s_config *)&reader[CS_MAXREADER];
676 #endif
677 #ifdef CS_LOGHISTORY
678 loghistidx=(int *)((void *)cfg+sizeof(struct s_config));
679 loghist=(char *)((void *)loghistidx+sizeof(int));
680 #endif
682 #ifdef DEBUG_SHM_POINTER
683 printf("SHM ALLOC: %x\n", shmsize);
684 printf("SHM START: %p\n", (void *) ecmcache);
685 printf("SHM ST1: %p %x (%x)\n", (void *) ecmidx, ((void *) ecmidx) - ((void *) ecmcache), CS_ECMCACHESIZE*(sizeof(struct s_ecm)));
686 printf("SHM ST2: %p %x (%x)\n", (void *) oscam_sem, ((void *) oscam_sem) - ((void *) ecmidx), sizeof(int));
687 printf("SHM ST3: %p %x (%x)\n", (void *) client, ((void *) client) - ((void *) oscam_sem), sizeof(int));
688 printf("SHM ST4: %p %x (%x)\n", (void *) reader, ((void *) reader) - ((void *) client), CS_MAXPID*(sizeof(struct s_client)));
689 printf("SHM ST5: %p %x (%x)\n", (void *) cfg, ((void *) cfg) - ((void *) reader), CS_MAXREADER*(sizeof(struct s_reader)));
690 printf("SHM ST6: %p %x (%x)\n", ((void *) cfg)+sizeof(struct s_config), sizeof(struct s_config), sizeof(struct s_config));
691 printf("SHM ENDE: %p\n", ((void *) cfg)+sizeof(struct s_config));
692 printf("SHM SIZE: %x\n", ((void *) cfg)-((void *) ecmcache) + sizeof(struct s_config));
693 fflush(stdout);
694 #endif
696 *ecmidx=0;
697 *logidx=0;
698 *oscam_sem=0;
699 client[0].pid=getpid();
700 client[0].login=time((time_t *)0);
701 client[0].ip=cs_inet_addr("127.0.0.1");
702 client[0].typ='s';
703 client[0].au=(-1);
704 client[0].dbglvl=cs_dblevel;
705 strcpy(client[0].usr, "root");
706 #ifdef CS_LOGHISTORY
707 *loghistidx=0;
708 memset(loghist, 0, CS_MAXLOGHIST*CS_LOGHISTSIZE);
709 #endif
712 static int start_listener(struct s_module *ph, int port_idx)
714 int ov=1, timeout, is_udp, i;
715 char ptxt[2][32];
716 //struct hostent *ptrh; /* pointer to a host table entry */
717 struct protoent *ptrp; /* pointer to a protocol table entry */
718 struct sockaddr_in sad; /* structure to hold server's address */
720 ptxt[0][0]=ptxt[1][0]='\0';
721 if (!ph->ptab->ports[port_idx].s_port)
723 cs_log("%s: disabled", ph->desc);
724 return(0);
726 is_udp=(ph->type==MOD_CONN_UDP);
728 memset((char *)&sad,0,sizeof(sad)); /* clear sockaddr structure */
729 sad.sin_family = AF_INET; /* set family to Internet */
730 if (!ph->s_ip)
731 ph->s_ip=cfg->srvip;
732 if (ph->s_ip)
734 sad.sin_addr.s_addr=ph->s_ip;
735 sprintf(ptxt[0], ", ip=%s", inet_ntoa(ph->s_ip));
737 else
738 sad.sin_addr.s_addr=INADDR_ANY;
739 timeout=cfg->bindwait;
740 //ph->fd=0;
741 ph->ptab->ports[port_idx].fd = 0;
743 if (ph->ptab->ports[port_idx].s_port > 0) /* test for illegal value */
744 sad.sin_port = htons((u_short)ph->ptab->ports[port_idx].s_port);
745 else
747 cs_log("%s: Bad port %d", ph->desc, ph->ptab->ports[port_idx].s_port);
748 return(0);
751 /* Map transport protocol name to protocol number */
753 if( (ptrp=getprotobyname(is_udp ? "udp" : "tcp")) )
754 ov=ptrp->p_proto;
755 else
756 ov=(is_udp) ? 17 : 6; // use defaults on error
758 if ((ph->ptab->ports[port_idx].fd=socket(PF_INET,is_udp ? SOCK_DGRAM : SOCK_STREAM, ov))<0)
760 cs_log("%s: Cannot create socket (errno=%d)", ph->desc, errno);
761 return(0);
764 ov=1;
765 if (setsockopt(ph->ptab->ports[port_idx].fd, SOL_SOCKET, SO_REUSEADDR, (void *)&ov, sizeof(ov))<0)
767 cs_log("%s: setsockopt failed (errno=%d)", ph->desc, errno);
768 close(ph->ptab->ports[port_idx].fd);
769 return(ph->ptab->ports[port_idx].fd=0);
772 #ifdef SO_REUSEPORT
773 setsockopt(ph->ptab->ports[port_idx].fd, SOL_SOCKET, SO_REUSEPORT, (void *)&ov, sizeof(ov));
774 #endif
776 #ifdef SO_PRIORITY
777 if (cfg->netprio)
778 if (!setsockopt(ph->ptab->ports[port_idx].fd, SOL_SOCKET, SO_PRIORITY, (void *)&cfg->netprio, sizeof(ulong)))
779 sprintf(ptxt[1], ", prio=%d", cfg->netprio);
780 #endif
782 if( !is_udp )
784 ulong keep_alive = 1;
785 setsockopt(ph->ptab->ports[port_idx].fd, SOL_SOCKET, SO_KEEPALIVE,
786 (void *)&keep_alive, sizeof(ulong));
789 while (timeout--)
791 if (bind(ph->ptab->ports[port_idx].fd, (struct sockaddr *)&sad, sizeof (sad))<0)
793 if (timeout)
795 cs_log("%s: Bind request failed, waiting another %d seconds",
796 ph->desc, timeout);
797 sleep(1);
799 else
801 cs_log("%s: Bind request failed, giving up", ph->desc);
802 close(ph->ptab->ports[port_idx].fd);
803 return(ph->ptab->ports[port_idx].fd=0);
806 else timeout=0;
809 if (!is_udp)
810 if (listen(ph->ptab->ports[port_idx].fd, CS_QLEN)<0)
812 cs_log("%s: Cannot start listen mode (errno=%d)", ph->desc, errno);
813 close(ph->ptab->ports[port_idx].fd);
814 return(ph->ptab->ports[port_idx].fd=0);
817 cs_log("%s: initialized (fd=%d, port=%d%s%s%s)",
818 ph->desc, ph->ptab->ports[port_idx].fd,
819 ph->ptab->ports[port_idx].s_port,
820 ptxt[0], ptxt[1], ph->logtxt ? ph->logtxt : "");
822 for( i=0; i<ph->ptab->ports[port_idx].ftab.nfilts; i++ ) {
823 int j;
824 cs_log("CAID: %04X", ph->ptab->ports[port_idx].ftab.filts[i].caid );
825 for( j=0; j<ph->ptab->ports[port_idx].ftab.filts[i].nprids; j++ )
826 cs_log("provid #%d: %06X", j, ph->ptab->ports[port_idx].ftab.filts[i].prids[j]);
828 return(ph->ptab->ports[port_idx].fd);
831 static void *cs_client_resolve(void *dummy)
833 while (1)
835 struct hostent *rht;
836 struct s_auth *account;
837 struct sockaddr_in udp_sa;
839 for (account=cfg->account; account; account=account->next)
840 if (account->dyndns[0])
842 if (rht=gethostbyname(account->dyndns))
844 memcpy(&udp_sa.sin_addr, rht->h_addr, sizeof(udp_sa.sin_addr));
845 account->dynip=cs_inet_order(udp_sa.sin_addr.s_addr);
847 else
848 cs_log("can't resolve hostname %s (user: %s)", account->dyndns, account->usr);
849 client[cs_idx].last=time((time_t)0);
851 sleep(cfg->resolvedelay);
855 static void start_client_resolver()
857 int i;
858 pthread_t tid;
860 if (i=pthread_create(&tid, (pthread_attr_t *)0, cs_client_resolve, (void *) 0))
861 cs_log("ERROR: can't create resolver-thread (err=%d)", i);
862 else
864 cs_log("resolver thread started");
865 pthread_detach(tid);
869 void cs_resolve()
871 int i, idx;
872 struct hostent *rht;
873 struct s_auth *account;
874 for (i=0; i<CS_MAXREADER; i++)
875 if ((idx=reader[i].cs_idx) && (reader[i].typ & R_IS_NETWORK))
877 client[cs_idx].last=time((time_t)0);
878 if (rht=gethostbyname(reader[i].device))
880 memcpy(&client[idx].udp_sa.sin_addr, rht->h_addr,
881 sizeof(client[idx].udp_sa.sin_addr));
882 client[idx].ip=cs_inet_order(client[idx].udp_sa.sin_addr.s_addr);
884 else
885 cs_log("can't resolve %s", reader[i].device);
886 client[cs_idx].last=time((time_t)0);
890 #ifdef USE_PTHREAD
891 static void *cs_logger(void *dummy)
892 #else
893 static void cs_logger(void)
894 #endif
896 *log_fd=client[cs_idx].fd_m2c;
897 while(1)
899 uchar *ptr;
900 //struct timeval tv;
901 fd_set fds;
903 FD_ZERO(&fds);
904 FD_SET(fd_m2c, &fds);
905 select(fd_m2c+1, &fds, 0, 0, 0);
906 #ifndef USE_PTHREAD
907 if (master_pid!=getppid())
908 cs_exit(0);
909 #endif
910 if (FD_ISSET(fd_m2c, &fds))
912 int n;
913 // switch(n=read_from_pipe(fd_m2c, &ptr, 1))
914 n=read_from_pipe(fd_m2c, &ptr, 1);
915 //if (n!=PIP_ID_NUL) printf("received %d bytes\n", n); fflush(stdout);
916 switch(n)
918 case PIP_ID_LOG:
919 cs_write_log(ptr);
920 break;
926 static void start_resolver()
928 int i;
929 #ifdef USE_PTHREAD
930 pthread_t tid;
931 if (i=pthread_create(&tid, (pthread_attr_t *)0, cs_logger, (void *) 0))
932 cs_log("ERROR: can't create logging-thread (err=%d)", i);
933 else
935 cs_log("logging thread started");
936 pthread_detach(tid);
938 #endif
939 sleep(1); // wait for reader
940 while(1)
942 if (master_pid!=getppid())
943 cs_exit(0);
944 cs_resolve();
945 for (i=0; i<cfg->resolvedelay; i++)
946 if (master_pid!=getppid())
947 cs_exit(0);
948 else
949 sleep(1);
950 // sleep(cfg->resolvedelay);
954 #ifdef CS_ANTICASC
955 static void start_anticascader()
957 int i;
959 use_ac_log=1;
960 set_signal_handler(SIGHUP, 1, ac_init_stat);
962 ac_init_stat(0);
963 while(1)
965 for( i=0; i<cfg->ac_stime*60; i++ )
966 if( master_pid!=getppid() )
967 cs_exit(0);
968 else
969 sleep(1);
971 if (master_pid!=getppid())
972 cs_exit(0);
974 ac_do_stat();
977 #endif
979 static void init_cardreader()
981 for (ridx=0; ridx<CS_MAXREADER; ridx++)
982 if (reader[ridx].device[0])
983 switch(cs_fork(0, 99))
985 case -1:
986 cs_exit(1);
987 case 0:
988 break;
989 default:
990 wait4master();
991 start_cardreader();
995 static void init_service(int srv)
997 switch(cs_fork(0, srv))
999 case -1:
1000 cs_exit(1);
1001 case 0:
1002 break;
1003 default:
1004 wait4master();
1005 switch(srv)
1007 #ifdef CS_ANTICASC
1008 case 96: start_anticascader();
1009 #endif
1010 case 97: cs_logger();
1011 case 98: start_resolver();
1016 void wait4master()
1018 int i;
1019 for (i=0; (i<1000) && (client[cs_idx].pid!=getpid()); i++)
1020 usleep(1000L);
1021 if (client[cs_idx].pid!=getpid())
1023 cs_log("PANIC: client not found in shared memory");
1024 cs_exit(1);
1026 cs_debug("starting client %d with ip %s",
1027 cs_idx-cdiff, cs_inet_ntoa(client[cs_idx].ip));
1030 static void cs_fake_client(char *usr)
1032 int i;
1033 for (i=cdiff+1; i<CS_MAXPID; i++)
1034 if ((client[i].pid) && (client[i].typ=='c') &&
1035 (!client[i].dup) && (!strcmp(client[i].usr, usr)))
1037 client[i].dup=1;
1038 client[i].au=(-1);
1039 cs_log("client %d duplicate user '%s', set to fake", i-cdiff, usr);
1043 int cs_auth_client(struct s_auth *account, char *e_txt)
1045 int rc=0;
1046 char buf[16];
1047 char *t_crypt="encrypted";
1048 char *t_plain="plain";
1049 char *t_grant=" granted";
1050 char *t_reject=" rejected";
1051 char *t_msg[]= { buf, "invalid access", "invalid ip", "unknown reason" };
1052 client[cs_idx].grp=0xffffffff;
1053 client[cs_idx].au=(-1);
1054 switch((long)account)
1056 case -2: // gbx-dummy
1057 client[cs_idx].dup=0;
1058 break;
1059 case 0: // reject access
1060 rc=1;
1061 cs_log("%s %s-client %s%s (%s)",
1062 client[cs_idx].crypted ? t_crypt : t_plain,
1063 ph[client[cs_idx].ctyp].desc,
1064 client[cs_idx].ip ? cs_inet_ntoa(client[cs_idx].ip) : "",
1065 client[cs_idx].ip ? t_reject : t_reject+1,
1066 e_txt ? e_txt : t_msg[rc]);
1067 break;
1068 default: // grant/check access
1069 if (client[cs_idx].ip && account->dyndns[0])
1070 if (client[cs_idx].ip != account->dynip)
1071 rc=2;
1072 if (!rc)
1074 client[cs_idx].dup=0;
1075 if (client[cs_idx].typ=='c')
1077 client[cs_idx].grp=account->grp;
1078 client[cs_idx].au=account->au;
1079 client[cs_idx].tosleep=(60*account->tosleep);
1080 memcpy(&client[cs_idx].ctab, &account->ctab, sizeof(client[cs_idx].ctab));
1081 if (account->uniq)
1082 cs_fake_client(account->usr);
1083 client[cs_idx].ftab = account->ftab; // IDENT filter
1084 client[cs_idx].cltab = account->cltab; // CLASS filter
1085 client[cs_idx].fchid = account->fchid; // CHID filter
1086 client[cs_idx].sidtabok= account->sidtabok; // services
1087 client[cs_idx].sidtabno= account->sidtabno; // services
1088 client[cs_idx].pcrc = crc32(0L, MD5(account->pwd, strlen(account->pwd), NULL), 16);
1089 premhack=account->premhack;
1090 #ifdef CS_ANTICASC
1091 ac_init_client(account);
1092 #endif
1095 client[cs_idx].monlvl=account->monlvl;
1096 strcpy(client[cs_idx].usr, account->usr);
1097 case -1: // anonymous grant access
1098 if (rc)
1099 t_grant=t_reject;
1100 else
1102 if (client[cs_idx].typ=='m')
1103 sprintf(t_msg[0], "lvl=%d", client[cs_idx].monlvl);
1104 else
1105 sprintf(t_msg[0], "au=%d", client[cs_idx].au+1);
1107 cs_log("%s %s-client %s%s (%s, %s)",
1108 client[cs_idx].crypted ? t_crypt : t_plain,
1109 e_txt ? e_txt : ph[client[cs_idx].ctyp].desc,
1110 client[cs_idx].ip ? cs_inet_ntoa(client[cs_idx].ip) : "",
1111 client[cs_idx].ip ? t_grant : t_grant+1,
1112 username(cs_idx), t_msg[rc]);
1113 break;
1115 return(rc);
1118 void cs_disconnect_client(void)
1120 char buf[32]={0};
1121 if (client[cs_idx].ip)
1122 sprintf(buf, " from %s", cs_inet_ntoa(client[cs_idx].ip));
1123 cs_log("%s disconnected%s", username(cs_idx), buf);
1124 cs_exit(0);
1127 int check_ecmcache(ECM_REQUEST *er, ulong grp)
1129 int i;
1130 // cs_ddump(ecmd5, CS_ECMSTORESIZE, "ECM search");
1131 //cs_log("cache CHECK: grp=%lX", grp);
1132 for(i=0; i<CS_ECMCACHESIZE; i++)
1133 if ((grp & ecmcache[i].grp) &&
1134 (!memcmp(ecmcache[i].ecmd5, er->ecmd5, CS_ECMSTORESIZE)))
1136 //cs_log("cache found: grp=%lX cgrp=%lX", grp, ecmcache[i].grp);
1137 memcpy(er->cw, ecmcache[i].cw, 16);
1138 return(1);
1140 return(0);
1143 static void store_ecm(ECM_REQUEST *er)
1145 //cs_log("store ecm from reader %d", er->reader[0]);
1146 memcpy(ecmcache[*ecmidx].ecmd5, er->ecmd5, CS_ECMSTORESIZE);
1147 memcpy(ecmcache[*ecmidx].cw, er->cw, 16);
1148 ecmcache[*ecmidx].caid=er->caid;
1149 ecmcache[*ecmidx].prid=er->prid;
1150 ecmcache[*ecmidx].grp =reader[er->reader[0]].grp;
1151 // cs_ddump(ecmcache[*ecmidx].ecmd5, CS_ECMSTORESIZE, "ECM stored (idx=%d)", *ecmidx);
1152 *ecmidx=(*ecmidx+1) % CS_ECMCACHESIZE;
1155 void store_logentry(char *txt)
1157 #ifdef CS_LOGHISTORY
1158 char *ptr;
1159 ptr=(char *)(loghist+(*loghistidx*CS_LOGHISTSIZE));
1160 ptr[0]='\1'; // make username unusable
1161 ptr[1]='\0';
1162 if ((client[cs_idx].typ=='c') || (client[cs_idx].typ=='m'))
1163 strncpy(ptr, client[cs_idx].usr, 31);
1164 strncpy(ptr+32, txt, CS_LOGHISTSIZE-33);
1165 *loghistidx=(*loghistidx+1) % CS_MAXLOGHIST;
1166 #endif
1170 * write_to_pipe():
1171 * write all kind of data to pipe specified by fd
1173 int write_to_pipe(int fd, int id, uchar *data, int n)
1175 uchar buf[1024+3+sizeof(int)];
1177 //printf("WRITE_START pid=%d", getpid()); fflush(stdout);
1178 if ((id<0) || (id>PIP_ID_MAX))
1179 return(PIP_ID_ERR);
1180 memcpy(buf, PIP_ID_TXT[id], 3);
1181 memcpy(buf+3, &n, sizeof(int));
1182 memcpy(buf+3+sizeof(int), data, n);
1183 n+=3+sizeof(int);
1184 //n=write(fd, buf, n);
1185 //printf("WRITE_END pid=%d", getpid()); fflush(stdout);
1186 //return(n);
1187 if( !fd )
1188 cs_log("write_to_pipe: fd==0");
1189 return(write(fd, buf, n));
1193 * read_from_pipe():
1194 * read all kind of data from pipe specified by fd
1195 * special-flag redir: if set AND data is ECM: this will redirected to appr. client
1197 int read_from_pipe(int fd, uchar **data, int redir)
1199 int rc;
1200 static int hdr=0;
1201 static uchar buf[1024+1+3+sizeof(int)];
1203 *data=(uchar *)0;
1204 rc=PIP_ID_NUL;
1206 if (!hdr)
1208 if (bytes_available(fd))
1210 if (read(fd, buf, 3+sizeof(int))==3+sizeof(int))
1211 memcpy(&hdr, buf+3, sizeof(int));
1212 else
1213 cs_log("WARNING: pipe header to small !");
1216 if (hdr)
1218 int l;
1219 for (l=0; (rc<0) && (PIP_ID_TXT[l]); l++)
1220 if (!memcmp(buf, PIP_ID_TXT[l], 3))
1221 rc=l;
1223 if (rc<0)
1225 fprintf(stderr, "WARNING: pipe garbage");
1226 fflush(stderr);
1227 cs_log("WARNING: pipe garbage");
1228 rc=PIP_ID_ERR;
1230 else
1232 l=hdr;
1233 if ((l+3-1+sizeof(int))>sizeof(buf))
1235 cs_log("WARNING: packet size (%d) to large", l);
1236 l=sizeof(buf)+3-1+sizeof(int);
1238 if (!bytes_available(fd))
1239 return(PIP_ID_NUL);
1240 hdr=0;
1241 if (read(fd, buf+3+sizeof(int), l)==l)
1242 *data=buf+3+sizeof(int);
1243 else
1245 cs_log("WARNING: pipe data to small !");
1246 return(PIP_ID_ERR);
1248 buf[l+3+sizeof(int)]=0;
1249 if ((redir) && (rc==PIP_ID_ECM))
1251 //int idx;
1252 ECM_REQUEST *er;
1253 er=(ECM_REQUEST *)(buf+3+sizeof(int));
1254 if( er->cidx && client[er->cidx].fd_m2c )
1255 write(client[er->cidx].fd_m2c, buf, l+3+sizeof(int));
1256 rc=PIP_ID_DIR;
1260 return(rc);
1264 * write_ecm_request():
1266 int write_ecm_request(int fd, ECM_REQUEST *er)
1268 return(write_to_pipe(fd, PIP_ID_ECM, (uchar *) er, sizeof(ECM_REQUEST)));
1271 int write_ecm_DCW(int fd, ECM_REQUEST *er)
1273 return(write_to_pipe(fd, PIP_ID_DCW, (uchar *) er, sizeof(ECM_REQUEST)));
1276 int write_ecm_answer(int fd, ECM_REQUEST *er)
1278 int i, f;
1279 uchar c;
1280 for (i=f=0; i<16; i+=4)
1282 c=((er->cw[i]+er->cw[i+1]+er->cw[i+2]) & 0xff);
1283 if (er->cw[i+3]!=c)
1285 f=1;
1286 er->cw[i+3]=c;
1289 if (f)
1290 cs_debug("notice: changed dcw checksum bytes");
1292 er->reader[0]=ridx;
1293 //cs_log("answer from reader %d (rc=%d)", er->reader[0], er->rc);
1294 er->caid=er->ocaid;
1295 if (er->rc==1||(er->gbxRidx&&er->rc==0)){
1296 store_ecm(er);
1299 return(write_ecm_request(fd, er));
1302 static int cs_read_timer(int fd, uchar *buf, int l, int msec)
1304 struct timeval tv;
1305 fd_set fds;
1306 int rc;
1308 if (!fd) return(-1);
1309 tv.tv_sec = msec / 1000;
1310 tv.tv_usec = (msec % 1000) * 1000;
1311 FD_ZERO(&fds);
1312 FD_SET(pfd, &fds);
1314 select(fd+1, &fds, 0, 0, &tv);
1316 rc=0;
1317 if (FD_ISSET(pfd, &fds))
1318 if (!(rc=read(fd, buf, l)))
1319 rc=-1;
1321 return(rc);
1324 ECM_REQUEST *get_ecmtask()
1326 int i, n;
1327 ECM_REQUEST *er=0;
1329 if (!ecmtask)
1331 n=(ph[client[cs_idx].ctyp].multi)?CS_MAXPENDING:1;
1332 if( (ecmtask=(ECM_REQUEST *)malloc(n*sizeof(ECM_REQUEST))) )
1333 memset(ecmtask, 0, n*sizeof(ECM_REQUEST));
1336 n=(-1);
1337 if (!ecmtask)
1339 cs_log("Cannot allocate memory (errno=%d)", errno);
1340 n=(-2);
1342 else
1343 if (ph[client[cs_idx].ctyp].multi)
1345 for (i=0; (n<0) && (i<CS_MAXPENDING); i++)
1346 if (ecmtask[i].rc<100)
1347 er=&ecmtask[n=i];
1349 else
1350 er=&ecmtask[n=0];
1352 if (n<0)
1353 cs_log("WARNING: ecm pending table overflow !");
1354 else
1356 memset(er, 0, sizeof(ECM_REQUEST));
1357 er->rc=100;
1358 er->cpti=n;
1359 er->cidx=cs_idx;
1360 cs_ftime(&er->tps);
1362 return(er);
1365 int send_dcw(ECM_REQUEST *er)
1367 static char *stxt[]={"found", "cache1", "cache2", "emu",
1368 "not found", "timeout", "sleeping",
1369 "fake", "invalid", "corrupt"};
1370 static char *stxtEx[]={"", "group", "caid", "ident", "class", "chid", "queue"};
1371 static char *stxtWh[]={"", "user ", "reader ", "server ", "lserver "};
1372 char sby[32]="";
1373 char erEx[32]="";
1374 char uname[38]="";
1375 struct timeb tpe;
1376 ushort lc, *lp;
1377 for (lp=(ushort *)er->ecm+(er->l>>2), lc=0; lp>=(ushort *)er->ecm; lp--)
1378 lc^=*lp;
1379 cs_ftime(&tpe);
1380 if(er->gbxFrom)
1381 snprintf(uname,sizeof(uname)-1, "%s(%04X)", username(cs_idx), er->gbxFrom);
1382 else
1383 snprintf(uname,sizeof(uname)-1, "%s", username(cs_idx));
1384 if (er->rc==0)
1386 if(reader[er->reader[0]].typ==R_GBOX)
1387 snprintf(sby, sizeof(sby)-1, " by %s(%04X)", reader[er->reader[0]].label,er->gbxCWFrom);
1388 else
1389 snprintf(sby, sizeof(sby)-1, " by %s", reader[er->reader[0]].label);
1391 if (er->rc<4) er->rcEx=0;
1392 if (er->rcEx)
1393 snprintf(erEx, sizeof(erEx)-1, "rejected %s%s", stxtWh[er->rcEx>>4],
1394 stxtEx[er->rcEx&0xf]);
1395 cs_log("%s (%04X&%06X/%04X/%02X:%04X): %s (%d ms)%s",
1396 uname, er->caid, er->prid, er->srvid, er->l, lc,
1397 er->rcEx?erEx:stxt[er->rc],
1398 1000*(tpe.time-er->tps.time)+tpe.millitm-er->tps.millitm, sby);
1399 er->caid=er->ocaid;
1400 switch(er->rc)
1402 case 2:
1403 case 1: client[cs_idx].cwcache++;
1404 case 3:
1405 case 0: client[cs_idx].cwfound++; break;
1406 default: client[cs_idx].cwnot++;
1407 if (er->rc>5)
1408 client[cs_idx].cwcache++;
1410 #ifdef CS_ANTICASC
1411 ac_chk(er, 1);
1412 #endif
1414 if( cfg->show_ecm_dw && !client[cs_idx].dbglvl )
1415 cs_dump(er->cw, 16, 0);
1416 if (er->rc==7) er->rc=0;
1417 ph[client[cs_idx].ctyp].send_dcw(er);
1418 return 0;
1421 static void chk_dcw(int fd)
1423 ECM_REQUEST *er, *ert;
1424 if (read_from_pipe(fd, (uchar **)&er, 0)!=PIP_ID_ECM)
1425 return;
1426 //cs_log("dcw check from reader %d for idx %d (rc=%d)", er->reader[0], er->cpti, er->rc);
1427 ert=&ecmtask[er->cpti];
1428 if (ert->rc<100)
1429 return; // already done
1430 if( (er->caid!=ert->caid) || memcmp(er->ecm , ert->ecm , sizeof(er->ecm)) )
1431 return; // obsolete
1432 ert->rcEx=er->rcEx;
1433 if (er->rc>0) // found
1435 ert->rc=(er->rc==2)?2:0;
1436 ert->rcEx=0;
1437 ert->reader[0]=er->reader[0];
1438 memcpy(ert->cw , er->cw , sizeof(er->cw));
1439 ert->gbxCWFrom=er->gbxCWFrom;
1441 else // not found (from ONE of the readers !)
1443 int i;
1444 ert->reader[er->reader[0]]=0;
1445 for (i=0; (ert) && (i<CS_MAXREADER); i++)
1446 if (ert->reader[i]) // we have still another chance
1447 ert=(ECM_REQUEST *)0;
1448 if (ert) ert->rc=4;
1450 if (ert) send_dcw(ert);
1451 return;
1454 ulong chk_provid(uchar *ecm, ushort caid)
1456 int i;
1457 ulong provid=0;
1458 switch(caid)
1460 case 0x100: // seca
1461 provid=b2i(2, ecm+3);
1462 break;
1463 case 0x500: // viaccess
1464 i=(ecm[4]==0xD2) ? 3 : 0; // tpsflag -> offset+3
1465 if ((ecm[5+i]==3) && ((ecm[4+i]==0x90) || (ecm[4+i]==0x40)))
1466 provid=(b2i(3, ecm+6+i) & 0xFFFFF0);
1467 default:
1468 // cryptoworks ?
1469 if( caid&0x0d00 && ecm[8]==0x83 && ecm[9]==1 )
1470 provid=(ulong)ecm[10];
1472 return(provid);
1476 void guess_irdeto(ECM_REQUEST *er)
1478 uchar b3;
1479 int b47;
1480 //ushort chid;
1481 struct s_irdeto_quess *ptr;
1483 b3 = er->ecm[3];
1484 ptr = cfg->itab[b3];
1485 if( !ptr ) {
1486 cs_debug("unknown irdeto byte 3: %02X", b3);
1487 return;
1489 b47 = b2i(4, er->ecm+4);
1490 //chid = b2i(2, er->ecm+6);
1491 //cs_debug("ecm: b47=%08X, ptr->b47=%08X, ptr->caid=%04X", b47, ptr->b47, ptr->caid);
1492 while( ptr )
1494 if( b47==ptr->b47 )
1496 if( er->srvid && (er->srvid!=ptr->sid) )
1498 cs_debug("sid mismatched (ecm: %04X, guess: %04X), wrong oscam.ird file?",
1499 er->srvid, ptr->sid);
1500 return;
1502 er->caid=ptr->caid;
1503 er->srvid=ptr->sid;
1504 er->chid=(ushort)ptr->b47;
1505 // cs_debug("quess_irdeto() found caid=%04X, sid=%04X, chid=%04X",
1506 // er->caid, er->srvid, er->chid);
1507 return;
1509 ptr=ptr->next;
1514 void guess_cardsystem(ECM_REQUEST *er)
1516 ushort last_hope=0;
1518 // viaccess - check by provid-search
1519 if( (er->prid=chk_provid(er->ecm, 0x500)) )
1520 er->caid=0x500;
1522 // nagra
1523 // is ecm[1] always 0x30 ?
1524 // is ecm[3] always 0x07 ?
1525 if ((er->ecm[6]==1) && (er->ecm[4]==er->ecm[2]-2))
1526 er->caid=0x1801;
1528 // seca2 - very poor
1529 if ((er->ecm[8]==0x10) && ((er->ecm[9]&0xF1)==1))
1530 last_hope=0x100;
1532 // is cryptoworks, but which caid ?
1533 if ((er->ecm[3]==0x81) && (er->ecm[4]==0xFF) &&
1534 (!er->ecm[5]) && (!er->ecm[6]) && (er->ecm[7]==er->ecm[2]-5))
1535 last_hope=0xd00;
1538 if (!er->caid && er->ecm[2]==0x31 && er->ecm[0x0b]==0x28)
1539 guess_irdeto(er);
1542 if (!er->caid) // guess by len ..
1543 er->caid=len4caid[er->ecm[2]+3];
1545 if (!er->caid)
1546 er->caid=last_hope;
1549 void request_cw(ECM_REQUEST *er, int flag)
1551 int i;
1552 er->level=flag;
1553 flag=(flag)?3:1; // flag specifies with/without fallback-readers
1554 for (i=0; i<CS_MAXREADER; i++)
1555 if (er->reader[i]&flag)
1556 write_ecm_request(reader[i].fd, er);
1559 void get_cw(ECM_REQUEST *er)
1561 int i, j, m, rejected;
1562 //uchar orig_caid[sizeof(er->caid)];
1563 time_t now;
1564 //test the guessing ...
1565 //cs_log("caid should be %04X, provid %06X", er->caid, er->prid);
1566 //er->caid=0;
1568 client[cs_idx].lastecm=time((time_t)0);
1570 if (!er->caid)
1571 guess_cardsystem(er);
1573 if( (er->caid & 0xFF00)==0x600 && !er->chid )
1574 er->chid = (er->ecm[6]<<8)|er->ecm[7];
1576 if (!er->prid)
1577 er->prid=chk_provid(er->ecm, er->caid);
1579 // quickfix for 0100:000065
1580 if (er->caid == 0x100 && er->prid == 0x65 && er->srvid == 0)
1581 er->srvid = 0x0642;
1583 if( (!er->prid) && client[cs_idx].ncd_server )
1585 int pi = client[cs_idx].port_idx;
1586 if( pi>=0 && cfg->ncd_ptab.nports && cfg->ncd_ptab.nports >= pi )
1587 er->prid = cfg->ncd_ptab.ports[pi].ftab.filts[0].prids[0];
1590 //cs_log("caid IS NOW .. %04X, provid %06X", er->caid, er->prid);
1592 rejected=0;
1593 if (er->rc>99) // rc<100 -> ecm error
1595 now=time((time_t *) 0);
1596 m=er->caid;
1597 er->ocaid=er->caid;
1599 i=er->srvid;
1600 if ((i!=client[cs_idx].last_srvid) || (!client[cs_idx].lastswitch))
1601 client[cs_idx].lastswitch=now;
1602 if ((client[cs_idx].tosleep) &&
1603 (now-client[cs_idx].lastswitch>client[cs_idx].tosleep))
1604 er->rc=6; // sleeping
1605 client[cs_idx].last_srvid=i;
1606 client[cs_idx].last_caid=m;
1608 for (j=0; (j<6) && (er->rc>99); j++)
1609 switch(j)
1611 case 0: if (client[cs_idx].dup)
1612 er->rc=7; // fake
1613 break;
1614 case 1: if (!chk_bcaid(er, &client[cs_idx].ctab))
1616 // cs_log("chk_bcaid failed");
1617 er->rc=8; // invalid
1618 er->rcEx=E2_CAID;
1620 break;
1621 case 2: if (!chk_srvid(er, cs_idx))
1622 er->rc=8;
1623 break;
1624 case 3: if (!chk_ufilters(er))
1625 er->rc=8;
1626 break;
1627 case 4: if (!chk_sfilter(er, ph[client[cs_idx].ctyp].ptab))
1628 er->rc=8;
1629 break;
1630 case 5: if( (i=er->l-(er->ecm[2]+3)) )
1632 if (i>0)
1634 cs_debug("warning: ecm size adjusted from 0x%X to 0x%X",
1635 er->l, er->ecm[2]+3);
1636 er->l=(er->ecm[2]+3);
1638 else
1639 er->rc=9; // corrupt
1641 break;
1644 if (premhack) // quickhack for 1801:000501
1645 // moved behind the check routines, because newcamd-ECM will fail if ecm is converted before
1646 if (er->caid==0x1801 && er->ecm[3]==7 && er->ecm[5]==5 && er->ecm[6]==1)
1648 int l;
1649 char hack[13]={0x70, 0x51, 0xc9, 0x00, 0x00, 0x00, 0x01, 0x10, 0x10, 0x00, 0x48, 0x12, 0x07};
1650 er->caid=0x1702;
1651 er->prid=0;
1652 er->l=(er->ecm[2]+3);
1653 memmove(er->ecm+14, er->ecm+4, er->l-1);
1654 memcpy(er->ecm+1, hack, 13);
1655 er->l+=10;
1656 er->ecm[2]=er->l-3;
1657 cs_debug("ecm converted 1801:000501 -> 1702:000000");
1660 memcpy(er->ecmd5, MD5(er->ecm, er->l, NULL), CS_ECMSTORESIZE);
1662 if (check_ecmcache(er, client[cs_idx].grp))
1663 er->rc=1; // cache1
1665 #ifdef CS_ANTICASC
1666 ac_chk(er, 0);
1667 #endif
1668 if( er->rc<100 && er->rc!=1 )
1669 rejected=1;
1672 if( !rejected && er->rc!=1 )
1674 for (i=m=0; i<CS_MAXREADER; i++)
1675 if (matching_reader(er, &reader[i])&&(i!=ridx))
1676 m|=er->reader[i]=(reader[i].fallback)?2:1;
1678 switch(m)
1680 case 0: er->rc=4; // no reader -> not found
1681 if (!er->rcEx) er->rcEx=E2_GROUP;
1682 break;
1683 case 2: for (i=0; i<CS_MAXREADER; i++) // fallbacks only, switch them.
1684 er->reader[i]>>=1;
1687 if (er->rc<100)
1689 if (cfg->delay) usleep(cfg->delay);
1690 send_dcw(er);
1691 return;
1694 er->rcEx=0;
1695 request_cw(er, 0);
1698 void log_emm_request(int auidx)
1700 // cs_log("%s send emm-request (reader=%s, caid=%04X)",
1701 // cs_inet_ntoa(client[cs_idx].ip), reader[auidx].label, reader[auidx].caid[0]);
1702 cs_log("%s emm-request sent (reader=%s, caid=%04X)",
1703 username(cs_idx), reader[auidx].label, reader[auidx].caid[0]);
1706 void do_emm(EMM_PACKET *ep)
1708 int au;//, ephs;
1709 au=client[cs_idx].au;
1711 if ((au<0) || (au>=CS_MAXREADER))
1712 return;
1713 client[cs_idx].lastemm=time((time_t)0);
1714 cs_ddump(reader[au].hexserial, 8, "reader serial:");
1715 cs_ddump(ep->hexserial, 8, "emm SA:");
1716 // if ((!reader[au].fd) || (reader[au].b_nano[ep->emm[3]])) // blocknano is obsolete
1717 if ((!reader[au].fd) || // reader has no fd
1718 (reader[au].caid[0]!=b2i(2,ep->caid)) || // wrong caid
1719 (memcmp(reader[au].hexserial, ep->hexserial, 8))) // wrong serial
1720 return;
1722 ep->cidx=cs_idx;
1723 write_to_pipe(reader[au].fd, PIP_ID_EMM, (uchar *) ep, sizeof(EMM_PACKET));
1726 static int comp_timeb(struct timeb *tpa, struct timeb *tpb)
1728 if (tpa->time>tpb->time) return(1);
1729 if (tpa->time<tpb->time) return(-1);
1730 if (tpa->millitm>tpb->millitm) return(1);
1731 if (tpa->millitm<tpb->millitm) return(-1);
1732 return(0);
1735 static void build_delay(struct timeb *tpe, struct timeb *tpc)
1737 if (comp_timeb(tpe, tpc)>0)
1739 tpe->time=tpc->time;
1740 tpe->millitm=tpc->millitm;
1744 struct timeval *chk_pending(struct timeb tp_ctimeout)
1746 int i;
1747 ulong td;
1748 struct timeb tpn, tpe, tpc; // <n>ow, <e>nd, <c>heck
1749 static struct timeval tv;
1751 ECM_REQUEST *er;
1752 cs_ftime(&tpn);
1753 tpe=tp_ctimeout; // latest delay -> disconnect
1755 if (ecmtask)
1756 i=(ph[client[cs_idx].ctyp].multi)?CS_MAXPENDING:1;
1757 else
1758 i=0;
1759 //cs_log("num pend=%d", i);
1760 for (--i; i>=0; i--)
1761 if (ecmtask[i].rc>=100) // check all pending ecm-requests
1763 int act, j;
1764 er=&ecmtask[i];
1765 tpc=er->tps;
1766 tpc.time+=(er->stage) ? cfg->ctimeout : cfg->ftimeout;
1767 if (!er->stage)
1769 for (j=0, act=1; (act) && (j<CS_MAXREADER); j++)
1770 if (er->reader[j]&1)
1771 act=0;
1772 //cs_log("stage 0, act=%d r0=%d, r1=%d, r2=%d, r3=%d, r4=%d r5=%d", act,
1773 // er->reader[0], er->reader[1], er->reader[2],
1774 // er->reader[3], er->reader[4], er->reader[5]);
1775 if (act)
1777 er->stage++;
1778 request_cw(er, er->stage);
1779 tpc.time+=cfg->ctimeout-cfg->ftimeout;
1782 if (comp_timeb(&tpn, &tpc)>0) // action needed
1784 //cs_log("Action now %d.%03d", tpn.time, tpn.millitm);
1785 //cs_log(" %d.%03d", tpc.time, tpc.millitm);
1786 if (er->stage)
1788 er->rc=5; // timeout
1789 send_dcw(er);
1790 continue;
1792 else
1794 er->stage++;
1795 request_cw(er, er->stage);
1796 tpc.time+=cfg->ctimeout-cfg->ftimeout;
1799 build_delay(&tpe, &tpc);
1801 td=(tpe.time-tpn.time)*1000+(tpe.millitm-tpn.millitm)+5;
1802 tv.tv_sec = td/1000;
1803 tv.tv_usec = (td%1000)*1000;
1804 //cs_log("delay %d.%06d", tv.tv_sec, tv.tv_usec);
1805 return(&tv);
1808 int process_input(uchar *buf, int l, int timeout)
1810 int rc;
1811 fd_set fds;
1812 struct timeb tp;
1814 if (master_pid!=getppid()) cs_exit(0);
1815 if (!pfd) return(-1);
1816 cs_ftime(&tp);
1817 tp.time+=timeout;
1818 if (ph[client[cs_idx].ctyp].watchdog)
1819 alarm(cfg->cmaxidle+2);
1820 while (1)
1822 FD_ZERO(&fds);
1823 FD_SET(pfd, &fds);
1824 FD_SET(fd_m2c, &fds);
1826 rc=select(((pfd>fd_m2c)?pfd:fd_m2c)+1, &fds, 0, 0, chk_pending(tp));
1827 if (master_pid!=getppid()) cs_exit(0);
1828 if (rc<0)
1830 if (errno==EINTR) continue;
1831 else return(0);
1834 if (FD_ISSET(fd_m2c, &fds)) // read from pipe
1835 chk_dcw(fd_m2c);
1837 if (FD_ISSET(pfd, &fds)) // read from client
1839 rc=ph[client[cs_idx].ctyp].recv(buf, l);
1840 break;
1842 if (tp.time<=time((time_t *)0)) // client maxidle reached
1844 rc=(-9);
1845 break;
1848 if (ph[client[cs_idx].ctyp].watchdog)
1849 alarm(cfg->cmaxidle+2);
1850 return(rc);
1853 static void process_master_pipe()
1855 int n;
1856 uchar *ptr;
1858 switch(n=read_from_pipe(mfdr, &ptr, 1))
1860 case PIP_ID_LOG:
1861 cs_write_log(ptr);
1862 break;
1863 case PIP_ID_HUP:
1864 cs_accounts_chk();
1865 break;
1869 void cs_log_config()
1871 uchar buf[2048];
1873 if (cfg->nice!=99)
1874 sprintf(buf, ", nice=%d", cfg->nice);
1875 else
1876 buf[0]='\0';
1877 cs_log("version=%s, system=%s%s", CS_VERSION_X, cs_platform(buf+64), buf);
1878 cs_log("max. clients=%d, client max. idle=%d sec",
1879 #ifdef CS_ANTICASC
1880 CS_MAXPID-3, cfg->cmaxidle);
1881 #else
1882 CS_MAXPID-2, cfg->cmaxidle);
1883 #endif
1884 if( cfg->max_log_size )
1885 sprintf(buf, "%d Kb", cfg->max_log_size);
1886 else
1887 strcpy(buf, "unlimited");
1888 cs_log("max. logsize=%s", buf);
1889 cs_log("client timeout=%d sec, cache delay=%d msec",
1890 cfg->ctimeout, cfg->delay);
1891 #ifdef CS_NOSHM
1892 cs_log("shared memory initialized (size=%d, fd=%d)", shmsize, shmid);
1893 #else
1894 cs_log("shared memory initialized (size=%d, id=%d)", shmsize, shmid);
1895 #endif
1898 int main (int argc, char *argv[])
1900 struct sockaddr_in cad; /* structure to hold client's address */
1901 int scad; /* length of address */
1902 //int fd; /* socket descriptors */
1903 int i, j, n;
1904 int bg=0;
1905 int gfd; //nph,
1906 int fdp[2];
1907 uchar buf[2048];
1908 void (*mod_def[])(struct s_module *)=
1910 module_monitor,
1911 module_camd33,
1912 module_camd35,
1913 module_camd35_tcp,
1914 module_newcamd,
1915 #ifdef CS_WITH_GBOX
1916 module_gbox,
1917 #endif
1918 module_radegast,
1919 module_oscam_ser,
1923 while ((i=getopt(argc, argv, "bc:d:hm:"))!=EOF)
1925 switch(i)
1927 case 'b': bg=1;
1928 break;
1929 case 'c': strncpy(cs_confdir, optarg, sizeof(cs_confdir)-1);
1930 break;
1931 case 'd': cs_dblevel=atoi(optarg);
1932 break;
1933 case 'm':
1934 #ifdef CS_NOSHM
1935 strncpy(cs_memfile, optarg, sizeof(cs_memfile)-1);
1936 break;
1937 #endif
1938 case 'h':
1939 default : usage();
1942 if (cs_confdir[strlen(cs_confdir)]!='/') strcat(cs_confdir, "/");
1943 init_shm();
1944 init_config();
1945 for (i=0; mod_def[i]; i++) // must be later BEFORE init_config()
1947 memset(&ph[i], 0, sizeof(struct s_module));
1948 mod_def[i](&ph[i]);
1951 cs_log("auth size=%d", sizeof(struct s_auth));
1952 //cs_log_config();
1953 cfg->delay*=1000;
1954 init_sidtab();
1955 init_readerdb();
1956 init_userdb();
1957 init_signal();
1958 cs_set_mloc(30, "init");
1959 init_srvid();
1960 init_len4caid();
1961 //init_irdeto_guess_tab();
1962 cs_init_statistics(cfg->usrfile);
1964 if (pipe(fdp))
1966 cs_log("Cannot create pipe (errno=%d)", errno);
1967 cs_exit(1);
1969 mfdr=fdp[0];
1970 fd_c2m=fdp[1];
1971 gfd=mfdr+1;
1973 if (bg && daemon(1,0))
1975 cs_log("Error starting in background (errno=%d)", errno);
1976 cs_exit(1);
1978 master_pid=client[0].pid=getpid();
1979 if (cfg->pidfile[0])
1981 FILE *fp;
1982 if (!(fp=fopen(cfg->pidfile, "w")))
1984 cs_log("Cannot open pid-file (errno=%d)", errno);
1985 cs_exit(1);
1987 fprintf(fp, "%d\n", getpid());
1988 fclose(fp);
1991 for (i=0; i<CS_MAX_MOD; i++)
1992 if( (ph[i].type & MOD_CONN_NET) && ph[i].ptab )
1993 for(j=0; j<ph[i].ptab->nports; j++)
1995 start_listener(&ph[i], j);
1996 if( ph[i].ptab->ports[j].fd+1>gfd )
1997 gfd=ph[i].ptab->ports[j].fd+1;
2000 start_client_resolver();
2001 init_service(97); // logger
2002 init_service(98); // resolver
2003 init_cardreader();
2004 #ifdef CS_ANTICASC
2005 if( !cfg->ac_enabled )
2006 cs_log("anti cascading disabled");
2007 else
2009 init_ac();
2010 init_service(96);
2012 #endif
2014 for (i=0; i<CS_MAX_MOD; i++)
2015 if (ph[i].type & MOD_CONN_SERIAL) // for now: oscam_ser only
2016 if (ph[i].s_handler)
2017 ph[i].s_handler(i);
2019 cs_close_log();
2020 *mcl=1;
2021 while (1)
2023 fd_set fds;
2027 FD_ZERO(&fds);
2028 FD_SET(mfdr, &fds);
2029 for (i=0; i<CS_MAX_MOD; i++)
2030 if ( (ph[i].type & MOD_CONN_NET) && ph[i].ptab )
2031 for (j=0; j<ph[i].ptab->nports; j++)
2032 if (ph[i].ptab->ports[j].fd)
2033 FD_SET(ph[i].ptab->ports[j].fd, &fds);
2034 errno=0;
2035 cs_set_mloc(0, "before select");
2036 select(gfd, &fds, 0, 0, 0);
2037 cs_set_mloc(60, "after select");
2038 } while (errno==EINTR);
2039 cs_set_mloc(-1, "event (global)");
2041 client[0].last=time((time_t *)0);
2042 scad = sizeof(cad);
2043 if (FD_ISSET(mfdr, &fds))
2045 cs_set_mloc(-1, "event: master-pipe");
2046 process_master_pipe();
2048 for (i=0; i<CS_MAX_MOD; i++)
2050 if( (ph[i].type & MOD_CONN_NET) && ph[i].ptab )
2052 for( j=0; j<ph[i].ptab->nports; j++ )
2054 if( ph[i].ptab->ports[j].fd && FD_ISSET(ph[i].ptab->ports[j].fd, &fds) )
2056 if (ph[i].type==MOD_CONN_UDP)
2058 cs_set_mloc(-1, "event: udp-socket");
2059 if ((n=recvfrom(ph[i].ptab->ports[j].fd, buf+3, sizeof(buf)-3, 0, (struct sockaddr *)&cad, &scad))>0)
2061 int idx;
2062 idx=idx_from_ip(cs_inet_order(cad.sin_addr.s_addr), ntohs(cad.sin_port));
2063 if (!idx)
2065 if (pipe(fdp))
2067 cs_log("Cannot create pipe (errno=%d)", errno);
2068 cs_exit(1);
2070 switch(cs_fork(cs_inet_order(cad.sin_addr.s_addr), ntohs(cad.sin_port)))
2072 case -1:
2073 close(fdp[0]);
2074 close(fdp[1]);
2075 break;
2076 case 0:
2077 client[idx=cs_last_idx].ufd=fdp[1];
2078 close(fdp[0]);
2079 break;
2080 default:
2081 // close(fdp[1]); // now used to simulate event
2082 pfd=fdp[0];
2083 wait4master();
2084 client[cs_idx].ctyp=i;
2085 client[cs_idx].port_idx=j;
2086 client[cs_idx].udp_fd=ph[i].ptab->ports[j].fd;
2087 client[cs_idx].udp_sa=cad;
2088 if (ph[client[cs_idx].ctyp].watchdog)
2089 alarm(cfg->cmaxidle<<2);
2090 ph[i].s_handler(cad); // never return
2093 if (idx)
2095 unsigned short rl;
2096 rl=n;
2097 buf[0]='U';
2098 memcpy(buf+1, &rl, 2);
2099 write(client[idx].ufd, buf, n+3);
2103 else
2105 cs_set_mloc(-1, "event: tcp-socket");
2106 if ((pfd=accept(ph[i].ptab->ports[j].fd, (struct sockaddr *)&cad, &scad))>0)
2108 switch(cs_fork(cs_inet_order(cad.sin_addr.s_addr), ntohs(cad.sin_port)))
2110 case -1:
2111 case 0:
2112 close(pfd);
2113 break;
2114 default:
2115 wait4master();
2116 client[cs_idx].ctyp=i;
2117 client[cs_idx].udp_fd=pfd;
2118 client[cs_idx].port_idx=j;
2119 if (ph[client[cs_idx].ctyp].watchdog)
2120 alarm(cfg->cmaxidle<<2);
2121 ph[i].s_handler();
2127 } // if (ph[i].type & MOD_CONN_NET)
2130 cs_exit(1);