예제 #1
0
int main(int argc, char **argv)
{
  int c, r;
  char *hostname, *service;
  struct tunsess *tun;
  struct sigaction sigact;
  int local_tunid;
  
  openlog("tunneldigger-client", 0, 0);

  while ((c = getopt(argc, argv, "dhfu:l:b:p:i:s:t:L:")) != EOF) {
    switch (c) {
    case 'h':			/* show help */
      print_help();
      exit(EXIT_SUCCESS);
      break;
    case 'f':			/* don't daemonize */
      dont_daemonize = 1;
      break;
    case 'd':
      debug_flag = 1;
      break;
    case 'u':			/* connection UUID */
      uuid = strdup(optarg);
      break;
    case 'l':			/* local IP address */
      local_ip = strdup(optarg);
      break;
    case 'b':			/* broker in <host>:<port> form */
      if (parse_broker(optarg, &hostname, &service) != 0) {
	fprintf(stderr, "invalid broker specification\n");
	exit(EXIT_FAILURE);
      }
      break;
    case 'i':			/* tunnel interface name */
      ifname = strdup(optarg);
      break;
    case 's':			/* hook script */
      script = strdup(optarg);
      break;
    case 't':			/* tunnel id */
      local_tunid = atoi(optarg);
      break;
    case 'L':			/* limit bandwidth down */
      limit_down = atoi(optarg);
      break;
    default:
      fprintf(stderr, "use '-h' for help\n", c);
      break;
    }
  }

  l2tp_init();

  if (!uuid) {
    printf ("the uuid is required\n");
    exit(EXIT_FAILURE);
  }

  tun = ts_new(hostname, service);
  tun->local_tunid = local_tunid;
  tun->ifname = strdup(ifname);

  /* create and bind a socket, and connect it */
  if ((r=ts_socket_bind_connect(tun)) != 0) {
    error("unable to obtain bound socket\n");
    exit(EXIT_FAILURE);
  }

  /* request a cookie */
  if ((r=ts_get_cookie(tun)) != 0) {
    error("unable to get cookie\n");
    exit(EXIT_FAILURE);
  }

  /* request a tunnel */
  if ((r=ts_get_tunnel(tun)) != 0) {
    error("unable to get tunnel\n");
    exit(EXIT_FAILURE);
  }

  /* create the tunnel */
  if (ts_create_tunnel(tun) != 0) {
    error("unable to create tunnel (is l2tp_eth loaded?)!\n");
    exit(EXIT_FAILURE);
  }

  /* handle SIGINT */
  sigact.sa_handler = signal_handler;
  sigemptyset(&sigact.sa_mask);
  if (sigaction(SIGINT, &sigact, NULL) < 0) {
    error("couldn't set signal handler\n");
  }

  /* keep the tunnel alive, and respond to PMTU discovery requests */
  ts_keepalive(tun);

  error("closing tunnel\n");

  if (ts_delete_tunnel(tun) != 0) {
    error("unable to delete tunnel!\n");
    exit(EXIT_FAILURE);
  }

  ts_close(tun);
}
static int
wlog_get_fmsaccesslog_lines(Tcl_Interp *interpreter, int fd,
                   uint32 start, uint32 end, Tcl_Obj **ret_list)
{
    Tcl_Obj *list = NULL;
    Tcl_Obj *line_obj = NULL;
    tstring *line_buf = NULL;
    char buf[wlog_log_buf_size];
    uint32 cur_line = 0;
    uint32 seg_start = 0;
    uint32 i = 0;
    int count = 0;
    int err = 0;
    char *cp;

    bail_null(ret_list);

    list = Tcl_NewListObj(0, NULL);
    bail_null(list);

    do {
        if (cur_line + 1 >= end) {
            break;
        }

        errno = 0;
        count = read(fd, buf, wlog_log_buf_size);
        if (count == -1 && errno == EINTR) { continue; }
        bail_require_errno(count >= 0, I_("Reading log file '%s'"),
                           file_fmsaccesslog_path);

        while (( cp = memchr(buf, '\0' , count )) != NULL )
            *cp = ' ';

        while (( cp = memchr(buf, '<' , count )) != NULL )
            *cp = '[';

        while (( cp = memchr(buf, '>' , count )) != NULL )
            *cp = ']';


        /* look for a newline inside the buffer */
        seg_start = 0;
        for (i = 0; i < (uint32)count; ++i) {
            if (buf[i] == '\n') {
                if (cur_line + 1 >= start && cur_line + 1 < end) {
                    if (!line_buf) {
                        err = ts_new(&line_buf);
                        bail_error(err);
                    }

                    err = ts_append_str_frag(line_buf, buf, seg_start,
                                             i - seg_start);
                    bail_error(err);

                    line_obj = Tcl_NewStringObj(ts_str(line_buf),
                                                ts_length(line_buf));
                    bail_null(line_obj);

                    err = Tcl_ListObjAppendElement(interpreter, list,
                                                   line_obj);
                    bail_require(err == TCL_OK);
                    err = 0;
                    
                    ts_free(&line_buf);
                }

                seg_start = i + 1;
                ++cur_line;
            }
        }

        if (seg_start < (uint32)count) {
            if (cur_line + 1 >= start && cur_line + 1 < end) {
                if (!line_buf) {
                    err = ts_new(&line_buf);
                    bail_error(err);
                }

                err = ts_append_str_frag(line_buf, buf, seg_start,
                                         (uint32)count - seg_start);
                bail_error(err);
            }
        }
    } while (count > 0);

    *ret_list = list;
    list = NULL;

 bail:
    if (list) {
        Tcl_DecrRefCount(list);
    }
    ts_free(&line_buf);
    return(err);
}
예제 #3
0
int main(int argc, char *argv[]) {
  int opt, i, n, rc=-1;
  struct epoll_event ev;
  CF.prog = argv[0];
  CF.now = time(NULL);
  utarray_new(CF.rdkafka_options,&ut_str_icd);
  utarray_new(CF.rdkafka_topic_options,&ut_str_icd);
  void *res;

  while ( (opt = getopt(argc, argv, "hv+N:n:d:b:t:c:C:")) != -1) {
    switch(opt) {
      case 'v': CF.verbose++; break;
      case 'n': CF.nthread=atoi(optarg); break;
      case 'd': CF.dir=strdup(optarg); break;
      case 't': CF.topic=strdup(optarg); break;
      case 'b': CF.broker=strdup(optarg); break;
      case 'c': utarray_push_back(CF.rdkafka_options,&optarg); break;
      case 'C': utarray_push_back(CF.rdkafka_topic_options,&optarg); break;
      case 'h': default: usage();
    }
  }
  if (CF.dir == NULL) usage();
  if (CF.broker == NULL) usage();
  if (CF.topic == NULL) CF.topic = CF.dir;

  /* stats (time series) for input/output tracking */
  CF.spr_msgs_ts = ts_new(6,  STATS_INTERVAL ,&ts_int_mm);
  CF.kaf_msgs_ts = ts_new(6,  STATS_INTERVAL, &ts_int_mm);
  CF.kaf_bytes_ts = ts_new(6, STATS_INTERVAL, &ts_int_mm);

  /* block all signals. we take signals synchronously via signalfd */
  sigset_t all;
  sigfillset(&all);
  sigprocmask(SIG_SETMASK,&all,NULL);

  /* a few signals we'll accept via our signalfd */
  sigset_t sw;
  sigemptyset(&sw);
  for(n=0; n < sizeof(sigs)/sizeof(*sigs); n++) sigaddset(&sw, sigs[n]);

  /* create the signalfd for receiving signals */
  CF.signal_fd = signalfd(-1, &sw, 0);
  if (CF.signal_fd == -1) {
    fprintf(stderr,"signalfd: %s\n", strerror(errno));
    goto done;
  }

  /* set up the epoll instance */
  CF.epoll_fd = epoll_create(1); 
  if (CF.epoll_fd == -1) {
    fprintf(stderr,"epoll: %s\n", strerror(errno));
    goto done;
  }

  if (setup_nano() < 0) goto done;

  /* add descriptors of interest */
  if (new_epoll(EPOLLIN, CF.signal_fd)) goto done; // signal socket

  /* fire up threads */
  rc = pthread_create(&CF.spr_thread, NULL, spr_worker, NULL); if (rc) goto done;
  CF.enc_thread = malloc(sizeof(pthread_t)*CF.nthread);
  if (CF.enc_thread == NULL) goto done;
  long id;
  for(i=0; i < CF.nthread; i++) {
    id = i;
    rc = pthread_create(&CF.enc_thread[i],NULL,enc_worker,(void*)id);
    if (rc) goto done;
  }

  CF.kaf_thread = malloc(sizeof(pthread_t)*CF.nthread);
  if (CF.kaf_thread == NULL) goto done;
  for(i=0; i < CF.nthread; i++) {
    id = i;
    rc = pthread_create(&CF.kaf_thread[i],NULL,kaf_worker,(void*)id);
    if (rc) goto done;
  }

  alarm(1);
  while (epoll_wait(CF.epoll_fd, &ev, 1, -1) > 0) {
    if (ev.data.fd == CF.signal_fd) { 
      if (handle_signal() < 0) goto done; 
    }
  }

  rc = 0;

done:
  CF.shutdown=1;
  nn_term();
  fprintf(stderr,"shutting down threads:\n");

  fprintf(stderr,"spoolreader...\n");
  if (CF.spr_thread) {
    pthread_cancel(CF.spr_thread);
    pthread_join(CF.spr_thread,NULL);
  }

  fprintf(stderr,"encoders...\n");
  if (CF.enc_thread) {
    for(i=0; i < CF.nthread; i++) {
      pthread_cancel(CF.enc_thread[i]);
      pthread_join(CF.enc_thread[i],NULL);
    }
  }

  fprintf(stderr,"transmitters...\n");
  if (CF.kaf_thread) {
    for(i=0; i < CF.nthread; i++) {
      pthread_cancel(CF.kaf_thread[i]);
      pthread_join(CF.kaf_thread[i],NULL);
    }
  }

  fprintf(stderr,"terminating...\n");
  if (CF.ingress_socket_push >= 0) nn_close(CF.ingress_socket_push);
  if (CF.ingress_socket_pull >= 0) nn_close(CF.ingress_socket_pull);
  if (CF.egress_socket_push >= 0) nn_close(CF.egress_socket_push);
  if (CF.egress_socket_pull >= 0) nn_close(CF.egress_socket_pull);
  if (CF.egress_socket_filepath) unlink(CF.egress_socket_filepath);
  if (CF.ingress_socket_filepath) unlink(CF.ingress_socket_filepath);
  if (CF.epoll_fd != -1) close(CF.epoll_fd);
  if (CF.signal_fd != -1) close(CF.signal_fd);
  ts_free(CF.spr_msgs_ts);
  ts_free(CF.kaf_msgs_ts);
  ts_free(CF.kaf_bytes_ts);
  if (CF.enc_thread) free(CF.enc_thread);
  if (CF.kaf_thread) free(CF.kaf_thread);
  utarray_free(CF.rdkafka_options);
  utarray_free(CF.rdkafka_topic_options);
  return rc;
}