root/trunk/src/renetcolSender.c @ 26

Revision 23, 10.1 KB (checked in by andreu, 16 years ago)

optimization : new param : myPtrs in checkdataflowset function

  • Property svn:eol-style set to native
Line 
1/*
2 * File: renetcolSender.c
3 *
4 * Authors: ANDREU François-Xavier
5 *
6 * Copyright (C) 2005 GIP RENATER
7 */
8
9/*  This file is part of renetcol.
10 *
11 *  renetcol is free software; you can redistribute it and/or modify
12 *  it under the terms of the GNU General Public License as published by
13 *  the Free Software Foundation; either version 2 of the License, or
14 *  (at your option) any later version.
15 *
16 *  renetcol is distributed in the hope that it will be useful,
17 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 *  GNU General Public License for more details.
20 *
21 *  You should have received a copy of the GNU General Public License
22 *  along with renetcol; if not, write to the Free Software
23 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
24 */
25
26#include "renetcolSender.h"
27
28key_t myKey = 0;
29int myQueue = 0;
30msgType myMsg;
31long type;
32RulesPtr rulesListPtr;
33char *rulesFileName;
34char *keyId;
35char *remoteHost;
36int i=0;
37int j=0;
38unsigned char *myText;
39unsigned char buffer2[2];
40unsigned char buffer4[4];
41unsigned short nb=0;
42unsigned short typeMsg = 0;
43RulesPtr tmp = NULL;
44
45/*
46 * todo
47 */
48int
49todo(int sock, char *host)
50{
51  char buffer[256];
52  int length;
53  FILE *ruleFile;
54  FILE *tmpFile;
55  char field[4];
56  char port[6];
57  char value[44];
58  char operator[2];
59  char lines[256][256];
60  char line[256];
61  char lineCopy[256];
62  char strTok[1];
63  char strName[100];
64  int cpt = 0;
65  int i = 0;
66  int ruleToDelete = 0;
67
68  while (1){
69    length = read(sock, buffer, 256);
70    if (length < 0){
71      syslog(LOG_ERR, " read : %s", strerror(errno));
72      return 1;
73    }
74    if (length == 0)
75      break;
76    buffer[length] = '\0';
77    if (strncmp("DELETE", buffer, 6)==0){
78      /* DELETE ALL RULES FROM A REMOTE CLIENT */
79      if (!(ruleFile = fopen(rulesFileName, "r"))) {
80        syslog (LOG_ERR, "error during %s opening\n", rulesFileName);
81        exit(1);
82      } else {
83        while ( fgets(line, 256, ruleFile) != 0) {
84          strncpy(lineCopy, line, 256);
85          if (strncmp("N", lineCopy, 1) == 0){
86            ruleToDelete = 0;
87            if (sscanf(lineCopy, "%1s %s\n",
88                       strTok,
89                       strName) != 0) {
90              if (strncmp(strName, host, strlen(host)) == 0){
91                ruleToDelete = 1;
92              } else {
93                strncpy(lines[cpt], line, strlen(line));
94              }
95            } else {
96              return 1;
97            }
98          } else {
99            if (ruleToDelete==0) {
100              strncpy(lines[cpt], lineCopy, strlen(lineCopy));
101            }
102          }
103          cpt++;
104        } /* while end */
105        fclose(ruleFile);
106        if (!(tmpFile = fopen("rules.tmp", "w"))) {
107          syslog (LOG_ERR, "error during %s opening", "rules.tmp");
108          return 1;
109        } else {
110          for (i=0; i<cpt; i++){
111            fprintf(tmpFile, "%s", lines[i]);
112          }
113          fclose(tmpFile);
114          if (remove("rules.txt")!=0){
115            syslog(LOG_ERR, "rules.txt remove pb: %s", strerror(errno));
116            return 1;
117          }
118          if (rename("rules.tmp", "rules.txt")!=0){
119            syslog(LOG_ERR, "rename file pb: %s", strerror(errno));
120            return 1;
121          }
122        }
123      }
124    } else {
125      /* NEW RULE */
126      if (sscanf(buffer, "%s %s %1s %s\n",
127                 port,
128                 field,
129                 operator,
130                 value) == 0) {
131        syslog (LOG_ERR, "error in recept rule: %s", buffer);
132        return 1;
133      }
134      if (!(ruleFile = fopen(rulesFileName, "a"))) {
135        syslog (LOG_ERR, "error during %s opening", rulesFileName);
136        return 1;
137      } else {
138        fprintf(ruleFile, "N %s\n", host);
139        fprintf(ruleFile, "O socket %s %s\n", host, port);
140        fprintf(ruleFile, "C %s %s %s\n", field, operator, value);
141        fclose(ruleFile);
142      }
143    }
144  }
145  close(sock);
146  return 0;
147}
148
149/*
150 * tcpServer
151 */
152int
153tcpServer ()
154{
155  struct addrinfo index, *result;
156  struct sockaddr_storage listenAddress;
157  socklen_t listenAddressLen;
158  int listenSock;
159  int returnCode;
160  pid_t renetcolPID = 0;
161  FILE *pidFile;
162  unsigned pid;
163  char line[256];
164  int status;
165
166  memset(&index, 0, sizeof index);
167  index.ai_flags = AI_PASSIVE;
168  index.ai_family = AF_UNSPEC;
169  index.ai_socktype = SOCK_STREAM;
170  index.ai_protocol = IPPROTO_TCP;
171  returnCode = getaddrinfo(NULL, RECEPT_PORT, &index, &result);
172  if (returnCode != 0) {
173    syslog(LOG_ERR, "getaddrinfo : %s", strerror(errno));
174    return -1;
175  }
176  listenAddressLen = result->ai_addrlen;
177  memcpy(&listenAddress, result->ai_addr, (size_t) listenAddressLen);   
178  listenSock = socket(result->ai_family, result->ai_socktype,
179                      result->ai_protocol);
180  if ( listenSock < 0) {
181    syslog(LOG_ERR, "socket : %s", strerror(errno));
182    freeaddrinfo(result);
183    return -1;
184  }
185  freeaddrinfo(result);
186 
187  {
188    int on = 1;
189    setsockopt(listenSock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof on);
190  }
191  if (bind(listenSock, (struct sockaddr *) &listenAddress,
192           listenAddressLen) < 0 ||
193      listen(listenSock, 8) < 0) {
194    syslog(LOG_ERR, "bind or listen : %s", strerror(errno));
195    return -1;
196  }
197  for (;;) {           
198    int clientSock;
199    struct sockaddr_storage clientAddress;
200    socklen_t clientAddressLen;
201    char host[NI_MAXHOST];
202   
203    memset(&clientAddress, 0, sizeof clientAddress);
204    clientAddressLen = (socklen_t) sizeof clientAddress;
205   
206    if ((clientSock =
207         accept(listenSock, (struct sockaddr *)
208                &clientAddress,
209                &clientAddressLen)) < 0) {
210      continue;
211    }
212    if (clientAddress.ss_family != AF_INET &&
213        clientAddress.ss_family != AF_INET6) {
214      close(clientSock);
215      continue;
216    }
217    if (getnameinfo((struct sockaddr *) &clientAddress,
218                    clientAddressLen, host, sizeof host,
219                    NULL, (size_t) 0, 0) == 0) {
220      syslog(LOG_INFO,
221             "New connection from %s", host);
222    }
223    remoteHost = host;
224    switch (fork ()) {
225    case 0 :
226      close (listenSock);
227      todo(clientSock, remoteHost);
228      if (!(pidFile = fopen("/tmp/pidrenetcol.tmp", "r"))) {
229        syslog (LOG_ERR, "error during /tmp/pidrenetcol.tmp opening : %s\n",
230                strerror(errno));
231        exit(1);
232      } else {
233        fgets(line, 256, pidFile);
234        if (sscanf(line, "%u", &pid)==0)
235          syslog(LOG_ERR,"sscanf : %s", strerror(errno));
236        renetcolPID = pid;
237      }
238      fclose(pidFile);
239      if (renetcolPID==0){
240        syslog(LOG_INFO, "PID null");
241      }else{
242        if (kill(renetcolPID, SIGUSR1)<0)
243          syslog(LOG_ERR, "I can't send SIGUSR1 to renetcol process : %s",
244                 strerror(errno));
245      }
246      exit (0);
247    case -1 :
248      syslog (LOG_ERR, "fork : %s", strerror(errno));
249      return (-1);
250    default :
251      close (clientSock);
252      if (waitpid( -1, &status, WNOHANG)==-1){
253        syslog(LOG_ERR, "waitpid : %s", strerror(errno));
254        exit(1);
255      }
256    }
257  }
258  return (0);
259}
260
261/*
262 *
263 */
264void initConfSender(){
265  RulesPtr tmp = NULL;
266
267  tmp = rulesListPtr;
268  for ( ; tmp; tmp=tmp->next) {
269    rulesListPtr = delRule(tmp, rulesListPtr);
270  }
271  rulesListPtr = NULL;
272  rulesListPtr = getRules(rulesListPtr, rulesFileName);
273  tmp = rulesListPtr;
274  for ( ; tmp; tmp=tmp->next) {
275    if (tmp->type != 2) {
276      rulesListPtr = delRule(tmp, rulesListPtr);
277    }
278  }
279  tmp = NULL;
280}
281
282/*
283 * Main
284 * ----
285 */
286int 
287main (int argc, char *argv[])
288{
289  int s=0;
290  unsigned short rulesID = 0;
291  FILE *pidFile;
292  pid_t renetcolPID = 0;
293
294  if ( argc != 4) {
295    fprintf (stderr,
296             "%s: Usage: %s <key> <msg type> <rules file>\n exp: %s renetcol 1 rules.txt\n",
297             argv[0], argv[0], argv[0]);
298    exit(1);
299  }
300  if (sscanf (argv[2], "%ld", &type) != 1){
301    fprintf(stderr, "renetcolSender: Error, Invalid message type in command\n");
302    exit(1);
303  } 
304
305  openlog(argv[0], LOG_PID, LOG_USER);
306  keyId = (char *) malloc((strlen(argv[1])+1) * sizeof(char));
307  strcpy (keyId, argv[1]);
308  rulesFileName = (char *) malloc((strlen(argv[3])+1) * sizeof(char));
309  strcpy (rulesFileName, argv[3]);
310  rulesListPtr = NULL;
311  fprintf(stderr, "renetcolSender: reading the rules...\n");
312  rulesListPtr = getRules(rulesListPtr, rulesFileName);
313  fprintf(stderr, "renetcolSender: OK\n");
314  /* we delete rules which are not type socket */
315  tmp = rulesListPtr;
316  for ( ; tmp; tmp=tmp->next) {
317    if (tmp->type != 2) {
318      rulesListPtr = delRule(tmp, rulesListPtr);
319    }
320  }
321  tmp = NULL;
322  /* get IPC messages queue */
323  if ((myKey = ftok(keyId, 0))== -1){
324    syslog(LOG_ERR, "ftok : %s", strerror(errno));
325    exit(1);
326  }
327  if ((myQueue = msgget(myKey, 0)) == -1){
328    syslog(LOG_ERR, "msgget : %s", strerror(errno));
329    exit(1);
330  }
331
332/*   chdir ("/"); */
333  fprintf(stderr, "renetcolSender: I become a deamon, next messages via syslogd. By.\n");
334  if (fork () != 0)
335    exit (0);
336  if (setsid() == -1){
337    exit(4);
338  }
339/*   for (i = 0; i < FOPEN_MAX; i ++) */
340/*     close (i); */
341 
342  /* launch a TCP server to listen remote clients */
343  switch (fork ()) {
344  case 0 : /* son */
345    tcpServer();
346  case -1 :
347    syslog (LOG_ERR, "fork : %s", strerror(errno));
348    return (-1);
349  default : /* father */
350    break;
351  }
352  /* loop on the message queue */
353  while (1) {
354    i=0;
355    myText = msgRcv(myQueue, &myMsg, type);
356    buffer2[0]= *(myText+i); i++;
357    buffer2[1]= *(myText+i); i++;
358    typeMsg = *((unsigned short *)&buffer2);
359    if (1==typeMsg){
360      /* we send the template definition to all the known destination */
361      tmp = rulesListPtr;
362      for ( ; tmp; tmp=tmp->next) {
363        s = sendMessage(tmp->host->sockId, myText, sizeof(myMsg.text),
364                        tmp->host->hostAddressPtr);
365      }
366    } else if (11==*((unsigned short*)&buffer2)){
367      buffer2[0]= *(myText+i); i++;
368      buffer2[1]= *(myText+i); i++;
369      rulesID = *((unsigned short *)&buffer2);
370      /* here we send the flow to the correct remote client */
371      tmp = rulesListPtr;
372      for ( ; tmp; tmp=tmp->next) { /* FIXME while */
373        if (tmp->id == rulesID){
374          s = sendMessage(tmp->host->sockId, myText, sizeof(myMsg.text),
375                          tmp->host->hostAddressPtr);
376        }
377      }
378    } else if (12==*((unsigned short*)&buffer2)){
379      buffer4[0]= *(myText+i); i++;
380      buffer4[1]= *(myText+i); i++;
381      buffer4[2]= *(myText+i); i++;
382      buffer4[3]= *(myText+i); i++;
383      renetcolPID = *((pid_t *)&buffer4);
384      if (!(pidFile = fopen("/tmp/pidrenetcol.tmp", "w"))) {
385        syslog (LOG_ERR, "error during /tmp/pidrenetcol.tmp opening : %s\n",
386                strerror(errno));
387        exit(1);
388      } else {
389        if (fprintf(pidFile, "%u", renetcolPID)==0)
390          syslog(LOG_ERR,"fprintf : %s", strerror(errno));
391      }
392      fclose(pidFile);
393    } else if (13==*((unsigned short*)&buffer2)){
394      initConfSender();
395    } else {
396      syslog(LOG_INFO, "Msg type undefined ??");
397    }
398    i=0;
399  }
400  return(0);
401}
Note: See TracBrowser for help on using the browser.