root/trunk/src/renetcolSender.c @ 73

Revision 73, 10.1 KB (checked in by andreu, 15 years ago)

last changes before next release

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