Exemplo n.º 1
0
static int retrieve_client_ips()
{
    int          count = 0, len, i;
    char        *split, *p, tmp_ip[32], *q;
    uint32_t     ip;

    p = clt_settings.raw_clt_ips;

    while (true) {
        split = strchr(p, ',');
        if (split != NULL) {
            *split = '\0';
        }

        len = strlen(p);
        if (len == 0) {
            tc_log_info(LOG_WARN, 0, "ip is empty");
            break;
        }

        if (p[len - 1] == '*') {
            strncpy(tmp_ip, p, len -1);
            q = tmp_ip + len - 1;
            for (i = 1; i < 255; i++) {
                sprintf(q, "%d", i);
                ip = inet_addr(tmp_ip);
                clt_settings.valid_ips[count++] = ip;
                if (count == M_CLIENT_IP_NUM) {
                    tc_log_info(LOG_WARN, 0, "reach the limit for clt ips");
                    break;

                }
            }
        } else {
            ip = inet_addr(p);
            clt_settings.valid_ips[count++] = ip;
            if (count == M_CLIENT_IP_NUM) {
                tc_log_info(LOG_WARN, 0, "reach the limit for clt ips");
                break;
            }


        }

        if (split != NULL) {
            *split = ',';
        }

        if (count == M_CLIENT_IP_NUM) {
            tc_log_info(LOG_WARN, 0, "reach the limit for clt_tf_ip");
            break;
        }

        if (split == NULL) {
            break;
        } else {
            p = split + 1;
        }

    }

    clt_settings.valid_ip_num = count;

    return 1;

}
Exemplo n.º 2
0
/*
 * main entry point
 */
int
main(int argc, char **argv)
{
    int ret, is_continue = 1;

    settings_init();

#if (TC_SIGACTION)
    if (set_signal_handler(signals) == -1) {
        return -1;
    }
#else
    signal(SIGINT,  tcp_copy_over);
    signal(SIGPIPE, tcp_copy_over);
    signal(SIGHUP,  tcp_copy_over);
    signal(SIGTERM, tcp_copy_over);
#endif

    tc_time_init();

    if (read_args(argc, argv) == -1) {
        return -1;
    }
    
    if (tc_log_init(clt_settings.log_path) == -1) {
        return -1;
    }

    clt_settings.pool = tc_create_pool(TC_DEFAULT_POOL_SIZE, 0, 0);

    if (clt_settings.pool == NULL) {
        return -1;
    }

    /* output debug info */
    output_for_debug();

    /* set details for running */
    if (set_details() == -1) {
        return -1;
    }

#if (TC_DIGEST)
    tc_init_digests(); 
    if (!tc_init_sha1()) {
        return -1;
    }
#endif

    tc_event_timer_init();

    ret = tc_event_loop_init(&event_loop, MAX_FD_NUM);
    if (ret == TC_EVENT_ERROR) {
        tc_log_info(LOG_ERR, 0, "event loop init failed");
        is_continue = 0;
    } 

    if (is_continue) {
        ret = tcp_copy_init(&event_loop);
        if (ret == TC_ERR) {
            is_continue = 0;
        }   
    }

    if (is_continue) {
        /* run now */
        tc_event_proc_cycle(&event_loop);
    }

    tcp_copy_release_resources();

    return 0;
}
Exemplo n.º 3
0
static int
tc_pcap_open(pcap_t **pd, char *device, int snap_len, int buf_size)
{
    int    status;
    char   ebuf[PCAP_ERRBUF_SIZE]; 

    *ebuf = '\0';

    *pd = pcap_create(device, ebuf);
    if (*pd == NULL) {
        tc_log_info(LOG_ERR, 0, "pcap create error:%s", ebuf);
        return TC_ERR;
    }

    status = pcap_set_snaplen(*pd, snap_len);
    if (status != 0) {
        tc_log_info(LOG_ERR, 0, "pcap_set_snaplen error:%s",
                pcap_statustostr(status));
        return TC_ERR;
    }

    status = pcap_set_promisc(*pd, 0);
    if (status != 0) {
        tc_log_info(LOG_ERR, 0, "pcap_set_promisc error:%s",
                pcap_statustostr(status));
        return TC_ERR;
    }

    status = pcap_set_timeout(*pd, 10);
    if (status != 0) {
        tc_log_info(LOG_ERR, 0, "pcap_set_timeout error:%s",
                pcap_statustostr(status));
        return TC_ERR;
    }

    status = pcap_set_buffer_size(*pd, buf_size);
    if (status != 0) {
        tc_log_info(LOG_ERR, 0, "pcap_set_buffer_size error:%s",
                pcap_statustostr(status));
        return TC_ERR;
    }

    tc_log_info(LOG_NOTICE, 0, "pcap_set_buffer_size:%d", buf_size);

#if (HAVE_SET_IMMEDIATE_MODE)
    status = pcap_set_immediate_mode(*pd, 1);
    if (status != 0) {
        tc_log_info(LOG_ERR, 0, "pcap_set_immediate_mode error:%s",
                pcap_statustostr(status));
        return TC_ERR;
    }
#endif

    status = pcap_activate(*pd);
    if (status < 0) {
        tc_log_info(LOG_ERR, 0, "pcap_activate error:%s",
                pcap_statustostr(status));
        return TC_ERR;

    } else if (status > 0) {
        tc_log_info(LOG_WARN, 0, "pcap activate warn:%s", 
                pcap_statustostr(status));
    }

    return TC_OK;
}
int tc_filter(frame_list_t *ptr_, char *options)
{
  vframe_list_t *ptr = (vframe_list_t *)ptr_;

  if(ptr->tag & TC_FILTER_GET_CONFIG) {

      optstr_filter_desc (options, MOD_NAME, MOD_CAP, MOD_VERSION, "Thomas Oestreich", "VRYE", "1");
      optstr_param (options, "mode",   "Choose the test pattern (0-4 interlaced, 5 colorfull)", "%d", "0", "0", "5");
  }

  //----------------------------------
  //
  // filter init
  //
  //----------------------------------

  if(ptr->tag & TC_FILTER_INIT) {

    if((vob = tc_get_vob())==NULL) return(-1);

    // filter init ok.

    if(verbose) tc_log_info(MOD_NAME, "%s %s", MOD_VERSION, MOD_CAP);

    if(verbose) tc_log_info(MOD_NAME, "options=%s", options);

    if (options) {
	if (is_optstr(options)) {
	    optstr_get(options, "mode", "%d", &mode);
	} else
	    sscanf(options, "%d", &mode);
    }

    if(mode <0) { tc_log_error(MOD_NAME, "Invalid mode"); return(-1); }

    return(0);
  }

  //----------------------------------
  //
  // filter close
  //
  //----------------------------------

  if(ptr->tag & TC_FILTER_CLOSE) {
    return(0);
  }

  //----------------------------------
  //
  // filter frame routine
  //
  //----------------------------------

  // tag variable indicates, if we are called before
  // transcodes internal video/audo frame processing routines
  // or after and determines video/audio context

  if(ptr->tag & TC_PRE_M_PROCESS && ptr->tag & TC_VIDEO && !(ptr->attributes & TC_FRAME_IS_SKIPPED)) {

    if(vob->im_v_codec==CODEC_RGB) {
      generate_rgb_frame(ptr->video_buf, ptr->v_width, ptr->v_height);
    } else {
      generate_yuv_frame(ptr->video_buf, ptr->v_width, ptr->v_height);
    }
  }
  return(0);
}
Exemplo n.º 5
0
static int
dispose_packet(char *recv_buf, int recv_len, int *p_valid_flag)
{
    int             replica_num, i, last, packet_num, max_payload,
                    index, payload_len;
    char           *packet, tmp_buf[RECV_BUF_SIZE];
    bool            packet_valid = false;
    uint16_t        id, size_ip, size_tcp, tot_len, cont_len,
                    pack_len = 0, head_len;
    uint32_t        seq;
    struct tcphdr  *tcp_header;
    struct iphdr   *ip_header;

    packet = recv_buf;

    if (is_packet_needed((const char *)packet)) {

        replica_num = clt_settings.replica_num;
        packet_num = 1;
        ip_header   = (struct iphdr*)packet;

        if (localhost == ip_header->saddr) {
            if (0 != clt_settings.lo_tf_ip) {
                ip_header->saddr = clt_settings.lo_tf_ip;
            }
        }

        /*
         * If packet length larger than MTU, then we split it.
         * This is to solve the ip fragmentation problem
         */
        if (recv_len > clt_settings.mtu) {

            /* Calculate number of packets */
            size_ip     = ip_header->ihl << 2;
            tot_len     = ntohs(ip_header -> tot_len);
            if (tot_len != recv_len) {
                tc_log_info(LOG_WARN, 0, "packet len:%u, recv len:%u",
                            tot_len, recv_len);
                return FAILURE;
            }

            tcp_header  = (struct tcphdr*)((char *)ip_header + size_ip);
            size_tcp    = tcp_header->doff << 2;
            cont_len    = tot_len - size_tcp - size_ip;
            head_len    = size_ip + size_tcp;
            max_payload = clt_settings.mtu - head_len;
            packet_num  = (cont_len + max_payload - 1)/max_payload;
            seq         = ntohl(tcp_header->seq);
            last        = packet_num - 1;
            id          = ip_header->id;

#if (TCPCOPY_DEBUG)
            tc_log_trace(LOG_NOTICE, 0, CLIENT_FLAG, ip_header, tcp_header);
#endif
            tc_log_debug1(LOG_DEBUG, 0, "recv:%d, more than MTU", recv_len);
            index = head_len;

            for (i = 0 ; i < packet_num; i++) {
                tcp_header->seq = htonl(seq + i * max_payload);
                if (i != last) {
                    pack_len  = clt_settings.mtu;
                } else {
                    pack_len += (cont_len - packet_num * max_payload);
                }
                payload_len = pack_len - head_len;
                ip_header->tot_len = htons(pack_len);
                ip_header->id = id++;
                /* Copy header here */
                memcpy(tmp_buf, recv_buf, head_len);
                /* Copy payload here */
                memcpy(tmp_buf + head_len, recv_buf + index, payload_len);
                index = index + payload_len;
                if (replica_num > 1) {
                    packet_valid = process_packet(true, tmp_buf, pack_len);
                    replicate_packs(tmp_buf, pack_len, replica_num);
                } else {
                    packet_valid = process_packet(false, tmp_buf, pack_len);
                }
            }
        } else {

            if (replica_num > 1) {

                packet_valid = process_packet(true, packet, recv_len);
                replicate_packs(packet, recv_len, replica_num);
            } else {

                packet_valid = process_packet(false, packet, recv_len);
            }
        }
    }

    if (packet_valid) {
        *p_valid_flag = 1;
    } else {
        *p_valid_flag = 0;
    }

    return SUCCESS;
}
Exemplo n.º 6
0
Arquivo: main.c Projeto: sunxu/tcpcopy
static int
set_details()
{
    int            rand_port;
    unsigned int   seed;
    struct timeval tp;

    /* generate a random port number for avoiding port conflicts */
    gettimeofday(&tp, NULL);
    seed = tp.tv_usec;
    rand_port = (int) ((rand_r(&seed)/(RAND_MAX + 1.0))*512);
    clt_settings.rand_port_shifted = rand_port;

    /* set the ip port pair mapping according to settings */
    if (retrieve_target_addresses(clt_settings.raw_transfer,
                              &clt_settings.transfer) == -1)
    {
        return -1;
    }

    if (clt_settings.percentage < 0 && clt_settings.percentage >99) {
        clt_settings.percentage = 0;
    }

#if (TCPCOPY_OFFLINE)
    if (clt_settings.pcap_file == NULL) {
        tc_log_info(LOG_ERR, 0, "it must have -i argument for offline");
        fprintf(stderr, "no -i argument\n");
        return -1;
    }
#endif

#if (TCPCOPY_PCAP)
    if (clt_settings.raw_device != NULL) {
        tc_log_info(LOG_NOTICE, 0, "device:%s", clt_settings.raw_device);
        if (strcmp(clt_settings.raw_device, DEFAULT_DEVICE) == 0) {
            clt_settings.raw_device = NULL; 
        } else {
            retrieve_devices();
        }
    }
#endif

#if (TCPCOPY_MYSQL_ADVANCED)
    if (clt_settings.user_pwd != NULL) {
        if (retrieve_mysql_user_pwd_info(clt_settings.user_pwd) == -1) {
            return -1;
        }
    } else {
        tc_log_info(LOG_ERR, 0, "it must have -u argument");
        fprintf(stderr, "no -u argument\n");
        return -1;
    }
#endif

#if (TCPCOPY_DR)
    /* retrieve real server ip addresses  */
    if (clt_settings.raw_rs_ip_list != NULL) {
        tc_log_info(LOG_NOTICE, 0, "s parameter:%s", 
                clt_settings.raw_rs_ip_list);
        retrieve_real_servers();
    } else {
        tc_log_info(LOG_WARN, 0, "no real server ip addresses");
        return -1;
    }
#endif

    /* daemonize */
    if (clt_settings.do_daemonize) {
        if (sigignore(SIGHUP) == -1) {
            tc_log_info(LOG_ERR, errno, "Failed to ignore SIGHUP");
        }
        if (daemonize() == -1) {
            fprintf(stderr, "failed to daemon() in order to daemonize\n");
            return -1;
        }    
    }    

#if (TCPCOPY_OFFLINE)
    if (tc_time_set_timer(TIMER_INTERVAL) == TC_ERROR) {
#else
    if (tc_time_set_timer(100) == TC_ERROR) {
#endif
        tc_log_info(LOG_ERR, 0, "set timer error");
        return -1;
    }

    return 0;
}

/* set default values for TCPCopy client */
static void
settings_init()
{
    /* init values */
    clt_settings.mtu = DEFAULT_MTU;
    clt_settings.mss = DEFAULT_MSS;
    clt_settings.max_rss = MAX_MEMORY_SIZE;
    clt_settings.srv_port = SERVER_PORT;
    clt_settings.percentage = 0;
    clt_settings.session_timeout = DEFAULT_SESSION_TIMEOUT;

    tc_raw_socket_out = TC_INVALID_SOCKET;

    set_signal_handler();
}
Exemplo n.º 7
0
/* initiate for tcpcopy server */
int
interception_init(tc_event_loop_t *event_loop, char *ip, uint16_t port)
{
    int         fd;
#if (INTERCEPT_THREAD)
    pthread_t   thread;
#endif
    tc_event_t *ev;

    router_init(srv_settings.hash_size);

    pid = getpid();

    /* init the listening socket */
    if ((fd = tc_socket_init()) == TC_INVALID_SOCKET) {
        return TC_ERROR;

    } else {
        if (tc_socket_listen(fd, ip, port) == TC_ERROR) {
            return TC_ERROR;
        }

        tc_log_info(LOG_NOTICE, 0, "msg listen socket:%d", fd);

        ev = tc_event_create(fd, tc_msg_event_accept, NULL);
        if (ev == NULL) {
            return TC_ERROR;
        }

        if (tc_event_add(event_loop, ev, TC_EVENT_READ) == TC_EVENT_ERROR) {
            return TC_ERROR;
        }
    }

    /* init the netlink socket */
    if ((fd = tc_nl_socket_init()) == TC_INVALID_SOCKET) {
        return TC_ERROR;

    } else {
        tc_log_info(LOG_NOTICE, 0, "firewall socket:%d", fd);

        ev = tc_event_create(fd, tc_nl_event_process, NULL);
        if (ev == NULL) {
            return TC_ERROR;
        }

        if (tc_event_add(event_loop, ev, TC_EVENT_READ) == TC_EVENT_ERROR) {
            return TC_ERROR;
        }
    }

#if (INTERCEPT_THREAD)
    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init(&full, NULL);
    pthread_cond_init(&empty, NULL);
    pthread_create(&thread, NULL, interception_process_msg, NULL);

    pthread_mutex_init(&nl_mutex, NULL);
    pthread_cond_init(&nl_full, NULL);
    pthread_cond_init(&nl_empty, NULL);
    pthread_create(&thread, NULL, interception_dispose_nl_verdict, NULL);
#endif

    return TC_OK;
}
/*
 * main function: check interlace state
 */
static void check_interlace (myfilter_t *myf, int id) {

    double pixDiff, pixShiftChangedT, pixShiftChangedB;
    double pixLastT, pixLastB, pixLast;
    int isChangedT = IS_FALSE,   isChangedB = IS_FALSE;
    int isProg     = IS_UNKNOWN;
    int isShift    = IS_UNKNOWN, isTop      = IS_UNKNOWN;
    int *counter = &myf->unknownFrames;

    /* Determine frame parmeters */
    pixDiff          = pic_compare (myf->lumInT, myf->lumInB,
				    myf->width, myf->height-2, 0);
    pixShiftChangedT = pic_compare (myf->lumInT, myf->lumPrevB,
				    myf->width, myf->height-2, 0);
    pixShiftChangedB = pic_compare (myf->lumInB, myf->lumPrevT,
				    myf->width, myf->height-2, 0);
    pixLastT         = pic_compare (myf->lumIn,  myf->lumPrev,
				    myf->width, myf->height/2, myf->width);
    pixLastB         = pic_compare (myf->lumIn   + myf->width,
				    myf->lumPrev + myf->width,
				    myf->width, myf->height/2, myf->width);
    pixLast = (pixLastT + pixLastB) / 2;

    /* Check for changed fields */
    if (pixLastT > myf->changedIfMore)
	isChangedT = IS_TRUE;
    if (pixLastB > myf->changedIfMore)
	isChangedB = IS_TRUE;

    /* Major field detection */
    if (pixShiftChangedT * myf->interlaceDiff < pixShiftChangedB)
	isTop = IS_TRUE;
    if (pixShiftChangedB * myf->interlaceDiff < pixShiftChangedT)
	isTop = IS_FALSE;

    /* Check for progessive frame */
    if (pixDiff * myf->unknownDiff > pixShiftChangedT ||
	pixDiff * myf->unknownDiff > pixShiftChangedB)
	isProg = IS_FALSE;
    if (pixDiff * myf->progressiveDiff < pixShiftChangedT &&
	pixDiff * myf->progressiveDiff < pixShiftChangedB &&
	pixDiff < pixLast * myf->progressiveChange)
	isProg = IS_TRUE;

    /* Check for shifted progressive frame */
    /* not completely equivalent to check.prog.frame. (pixLast) */
    /* TODO: this triggers too often for regular interlaced material */
    if (pixShiftChangedT * myf->progressiveDiff < pixDiff &&
	pixShiftChangedT * myf->progressiveDiff < pixShiftChangedB &&
	pixShiftChangedT < myf->progressiveChange * pixLast)
	isShift = IS_TRUE;
    if (pixShiftChangedB * myf->progressiveDiff < pixDiff &&
	pixShiftChangedB * myf->progressiveDiff < pixShiftChangedT &&
	pixShiftChangedT < myf->progressiveChange * pixLast)
	isShift = IS_TRUE;

    /* Detect telecine */
    /* telecined material will create a sequence like this (TopfieldFirst):
     * 0t1b (0)1t1b (1)2t2b (2)3t3b (3)3t4b (4)4t5b (0)5t5b ...
     * and vice versa for BottomfieldFirst.
     * We start looking for an progressive frame (1t1b) with one field
     * equal to the last frame and continue checking the frames for
     * adhering to the pattern.
     * We only count frames as valid telecine frames, if the pattern has been
     * detected twice in a row (telecineState > 10).
     * Undecidable frames (isProg == UNKNOWN && isTop == UNKNOWN) and
     * frames without changes (isChangedT != TRUE && isChangedB != TRUE)
     * are only accepted, if telecineState > 10.
     * Only happens for NTSC (29.97fps).
     * If a test fails, it reduces the current telecineState by 20.
     * Max. telecineState is 100.
     */
    /* TODO: currently no field insertion/deletion is detected,
     * requires resync right now */
    if ((myf->fps > 29.9 && myf->fps < 30.1) || myf->forceTelecineDetect) {

	if ((isChangedT == IS_TRUE || isChangedB == IS_TRUE) &&
	    (isProg != IS_UNKNOWN || isTop != IS_UNKNOWN ||
	     myf->telecineState > 10)){

	    switch (myf->telecineState % 5) {
	    case 0:
/*		if (isProg == IS_FALSE)
		myf->telecineState -= 20; */ /* prog. detmination may fail */
		switch (isTop) {
		case IS_TRUE:
		    if (isChangedB == IS_TRUE)
			myf->telecineState -= 20;
		    break;
		case IS_FALSE:
		    if (isChangedT == IS_TRUE)
			myf->telecineState -= 20;
		    break;
		}
		break;
	    case 1:
	    case 2:
		if (isProg == IS_FALSE)
		    myf->telecineState -= 20;
		break;
	    case 3:
		if (isProg == IS_TRUE)
		    myf->telecineState -= 20;
		switch (isTop) {
		case IS_TRUE:
		    if (isChangedT == IS_TRUE)
			myf->telecineState -= 20;
		    break;
		case IS_FALSE:
		    if (isChangedB == IS_TRUE)
			myf->telecineState -= 20;
		    break;
		}
		break;
	    case 4:
		if (isProg == IS_TRUE)
		    myf->telecineState -= 20;
		break;
	    }
	    if (myf->telecineState < 0)
		myf->telecineState = 0;
	    if (myf->telecineState == 0) {
		/* Frame has another chance to be case 0 */
/*		if (isProg == IS_FALSE)
		myf->telecineState = -1; */ /* prog. detmination may fail */
		switch (isTop) {
		case IS_TRUE:
		    if (isChangedB == IS_TRUE)
			myf->telecineState = -1;
		    break;
		case IS_FALSE:
		    if (isChangedT == IS_TRUE)
			myf->telecineState = -1;
		    break;
		}
	    }
	    myf->telecineState++;
	}
	else if (myf->telecineState > 10)
	    myf->telecineState++;
	else
	    myf->telecineState = 0;
	if (myf->telecineState > 100)
	    myf->telecineState -= 10;
    }


    /* Detect inconstistencies */
    if (isProg == IS_FALSE && isTop == IS_UNKNOWN)
	isProg = IS_UNKNOWN;
    if (isProg != IS_FALSE && isTop != IS_UNKNOWN) {
	isTop  = IS_UNKNOWN;
	isProg = IS_UNKNOWN;
    }
    if (isChangedT == IS_FALSE || isChangedB == IS_FALSE) {
	isProg  = IS_UNKNOWN;
	isTop   = IS_UNKNOWN;
	isShift = IS_UNKNOWN;
    }

    /* verbose output */
    if (myf->verbose) {
	char verboseBuffer[64];
	char *outType = 0, *outField = " ";

	memset (verboseBuffer, ' ', 63);

	if (pixDiff * myf->unknownDiff < pixShiftChangedT)
	    memcpy (&verboseBuffer[0], "pt", 2);
	if (pixDiff * myf->progressiveDiff < pixShiftChangedT)
	    memcpy (&verboseBuffer[0], "Pt", 2);
	if (pixDiff * myf->unknownDiff < pixShiftChangedB)
	    memcpy (&verboseBuffer[2], "pb", 2);
	if (pixDiff * myf->progressiveDiff < pixShiftChangedB)
	    memcpy (&verboseBuffer[2], "Pb", 2);

	if (pixDiff < myf->progressiveChange*pixLast)
	    verboseBuffer[5] = 'c';
	if (pixShiftChangedT * myf->interlaceDiff < pixShiftChangedB)
	    verboseBuffer[7] = 't';
	if (pixShiftChangedB * myf->interlaceDiff < pixShiftChangedT)
	    verboseBuffer[7] = 'b';

	if (isChangedT == IS_FALSE)
	    memcpy (&verboseBuffer[9], "st", 2);
	if (isChangedB == IS_FALSE)
	    memcpy (&verboseBuffer[11], "sb", 2);

	verboseBuffer[13] = 0;

	if (myf->verbose > 1) {
	    tc_log_info (MOD_NAME, "frame %d: pixDiff %.3f "
                     "pixShiftChanged %.3fT/%.3fB pixLast %.3fT/%.3fB telecineState %d",
		     id, pixDiff, pixShiftChangedT, pixShiftChangedB, pixLastT, pixLastB,
		     myf->telecineState);
	}

	switch (isProg) {
	case IS_UNKNOWN:	outType = "unknown    ";	break;
	case IS_FALSE:		outType = "interlaced ";	break;
	case IS_TRUE:		outType = "progressive";	break;
	}
	if (isChangedT == IS_FALSE && isChangedB == IS_FALSE)
	    outType = "low change ";
	if (isShift == IS_TRUE)
	    outType = "shifted p  ";
	if (myf->telecineState > 10)
	    outType = "telecined  ";
	switch (isTop) {
	case IS_FALSE:		outField = "B";			break;
	case IS_TRUE:		outField = "T";			break;
	}

	tc_log_info (MOD_NAME, "frame %d: %s  %s   [%s]",
		 id, outType, outField, verboseBuffer);
    }

    /* Count types */
    switch (isProg) {
    case IS_UNKNOWN:	counter = &myf->unknownFrames;		break;
    case IS_FALSE:	counter = &myf->interlacedFrames;	break;
    case IS_TRUE:	counter = &myf->progressiveFrames;	break;
    }
    if (isChangedT == IS_FALSE && isChangedB == IS_FALSE)
	counter = &myf->unknownFrames;
    if (isShift == IS_TRUE)
	counter = &myf->fieldShiftFrames;
    if (myf->telecineState > 10)
	counter = &myf->telecineFrames;
    switch (isTop) {
	case IS_FALSE:	myf->bottomFirstFrames++;		break;
	case IS_TRUE:	myf->topFirstFrames++;			break;
    }
    assert (counter);
    (*counter)++;
    myf->numFrames++;

}
/*
 * transcode API
 */
int tc_filter(frame_list_t *ptr_, char *options)
{
    vframe_list_t *ptr = (vframe_list_t *)ptr_;
    vob_t *vob = NULL;
    myfilter_t *myf = myf_global;

    /*
     * filter init
     */
    if (ptr->tag & TC_FILTER_INIT) {

	if (! (vob = tc_get_vob ()))
	    return -1;

	if (! (myf = myf_global = tc_zalloc (sizeof (myfilter_t)))) {
	    return -1;
	}

	if (! (myf->tcvhandle = tcv_init())) {
	    tc_log_error(MOD_NAME, "tcv_init() failed");
	    free(myf);
	    myf = myf_global = NULL;
	    return -1;
	}

	if (verbose)			/* global verbose */
	    tc_log_info(MOD_NAME, "%s %s", MOD_VERSION, MOD_CAP);

	/* default values */
	myf->interlaceDiff       = 1.1;
	myf->unknownDiff         = 1.5;
	myf->progressiveDiff     = 8;
	myf->progressiveChange   = 0.2;
	myf->changedIfMore       = 10;

	myf->forceTelecineDetect = 0;
	myf->verbose             = 0;
	myf->outDiff             = 0;

	/* video parameters */
	switch (vob->im_v_codec) {
	case TC_CODEC_YUY2:
	case TC_CODEC_YUV420P:
	case TC_CODEC_YUV422P:
	case TC_CODEC_RGB24:
	    break;
	default:
	    tc_log_error(MOD_NAME,
                     "Unsupported codec - need one of RGB24 YUV420P YUY2 YUV422P");
	    return -1;
	}
	myf->codec     = vob->im_v_codec;
	myf->width     = vob->im_v_width;
	myf->height    = vob->im_v_height;
	myf->fps       = vob->fps;
	myf->size = myf->width * myf->height;

	if (options) {
	    optstr_get (options, "interlacediff",     "%lf",
			&myf->interlaceDiff);
	    optstr_get (options, "unknowndiff",       "%lf",
			&myf->unknownDiff);
	    optstr_get (options, "progressivediff",   "%lf",
			&myf->progressiveDiff);
	    optstr_get (options, "progressivechange", "%lf",
			&myf->progressiveChange);
	    optstr_get (options, "changedifmore",     "%lf",
			&myf->changedIfMore);
	    optstr_get (options, "forcetelecinedetect",
		        "%d", &myf->forceTelecineDetect);
	    optstr_get (options, "verbose",          "%d", &myf->verbose);
	    optstr_get (options, "outdiff",          "%d", &myf->outDiff);

	    if (optstr_lookup (options, "help") != NULL) {
		tc_log_info (MOD_NAME, "(%s) help\n"
"* Overview:\n"
"  'fieldanalysis' scans video for interlacing artifacts and\n"
"  detects progressive / interlaced / telecined video.\n"
"  It also determines the major field for interlaced video.\n"
"* Verbose Output:   [PtPb c t stsb]\n"
"  Pt, Pb:   progressivediff succeeded, per field.\n"
"  pt, pb:   unknowndiff succeeded, progressivediff failed.\n"
"  c:        progressivechange succeeded.\n"
"  t:        topFieldFirst / b: bottomFieldFirst detected.\n"
"  st, sb:   changedifmore failed (fields are similar to last frame).\n"
			     , MOD_CAP);
	    }
	}

	/* frame memory */
	if (! (myf->lumIn    = calloc (1, myf->size)) ||
	    ! (myf->lumPrev  = calloc (1, myf->size)) ||
	    ! (myf->lumInT   = calloc (1, myf->size)) ||
	    ! (myf->lumInB   = calloc (1, myf->size)) ||
	    ! (myf->lumPrevT = calloc (1, myf->size)) ||
	    ! (myf->lumPrevB = calloc (1, myf->size))) {
	    tc_log_error(MOD_NAME, "calloc() failed");
	    return -1;
	}

	if (verbose) {			/* global verbose */
	    tc_log_info(MOD_NAME, "interlacediff %.2f,  unknowndiff %.2f,  progressivediff %.2f",
		                        myf->interlaceDiff, myf->unknownDiff, myf->progressiveDiff);
        tc_log_info(MOD_NAME, "progressivechange %.2f, changedifmore %.2f",
                    		   myf->progressiveChange, myf->changedIfMore);
        tc_log_info(MOD_NAME, "forcetelecinedetect %s, verbose %d, outdiff %d",
                    		   myf->forceTelecineDetect ? "True":"False", myf->verbose,
                               myf->outDiff);
	}

	return 0;
    }

    /*
     * filter close
     */

    if (ptr->tag & TC_FILTER_CLOSE) {

	int total = myf->numFrames - myf->unknownFrames;
	int totalfields = myf->topFirstFrames + myf->bottomFirstFrames;

	/* Cleanup */
	free (myf->lumIn);
	free (myf->lumPrev);
	free (myf->lumInT);
	free (myf->lumInB);
	free (myf->lumPrevT);
	free (myf->lumPrevB);
	myf->lumIn = myf->lumPrev = myf->lumInT = myf->lumInB =
	    myf->lumPrevT = myf->lumPrevB = NULL;

	/* Output results */
	if (totalfields < 1)
	    totalfields = 1;
	tc_log_info(MOD_NAME, "RESULTS: Frames:      %d (100%%)  Unknown:      %d (%.3g%%)",
		                myf->numFrames, myf->unknownFrames,
                		100.0 * myf->unknownFrames / (double)myf->numFrames);
    tc_log_info(MOD_NAME, "RESULTS: Progressive: %d (%.3g%%)  Interlaced:   %d (%.3g%%)",
		myf->progressiveFrames, 100.0 * myf->progressiveFrames / (double)myf->numFrames,
		myf->interlacedFrames, 100.0 * myf->interlacedFrames / (double)myf->numFrames);
    tc_log_info(MOD_NAME, "RESULTS: FieldShift:  %d (%.3g%%)  Telecined:    %d (%.3g%%)",
		myf->fieldShiftFrames, 100.0 * myf->fieldShiftFrames / (double)myf->numFrames,
		myf->telecineFrames, 100.0 * myf->telecineFrames / (double)myf->numFrames);
    tc_log_info(MOD_NAME, "RESULTS: MajorField: TopFirst %d (%.3g%%)  BottomFirst %d (%.3g%%)",
		myf->topFirstFrames, 100.0 * myf->topFirstFrames / (double)totalfields,
		myf->bottomFirstFrames, 100.0 * myf->bottomFirstFrames / (double)totalfields);

	if (total < 50)
	    tc_log_warn (MOD_NAME, "less than 50 frames analyzed correctly, no conclusion.");
	else if (myf->unknownFrames * 10 > myf->numFrames * 9)
	    tc_log_warn (MOD_NAME, "less than 10%% frames analyzed correctly, no conclusion.");
	else if (myf->progressiveFrames * 8 > total * 7)
	    tc_log_info (MOD_NAME, "CONCLUSION: progressive video.");
	else if (myf->topFirstFrames * 8 > myf->bottomFirstFrames &&
		 myf->bottomFirstFrames * 8 > myf->topFirstFrames)
	    tc_log_info (MOD_NAME, "major field unsure, no conclusion. Use deinterlacer for processing.");
	else if (myf->telecineFrames * 4 > total * 3)
	    tc_log_info (MOD_NAME, "CONCLUSION: telecined video, %s field first.",
                        myf->topFirstFrames > myf->bottomFirstFrames ? "top" : "bottom");
	else if (myf->fieldShiftFrames * 4 > total * 3)
	    tc_log_info (MOD_NAME, "CONCLUSION: field shifted progressive video, %s field first.",
                        myf->topFirstFrames > myf->bottomFirstFrames ? "top" : "bottom");
	else if (myf->interlacedFrames > myf->fieldShiftFrames &&
		 (myf->interlacedFrames+myf->fieldShiftFrames) * 8 > total * 7)
	    tc_log_info (MOD_NAME, "CONCLUSION: interlaced video, %s field first.",
                        myf->topFirstFrames > myf->bottomFirstFrames ? "top" : "bottom");
	else
	    tc_log_info (MOD_NAME, "mixed video, no conclusion. Use deinterlacer for processing.");

	tcv_free(myf->tcvhandle);
	myf->tcvhandle = 0;

	return 0;
    }

    /*
     * filter description
     */
    if (ptr->tag & TC_FILTER_GET_CONFIG) {
	char buf[255];
	optstr_filter_desc (options, MOD_NAME, MOD_CAP, MOD_VERSION,
			    MOD_AUTHOR, "VRY4E", "2");
	tc_snprintf (buf, sizeof(buf), "%g", myf->interlaceDiff);
	optstr_param (options, "interlacediff", "Minimum temporal inter-field difference for detecting interlaced video", "%f", buf, "1.0", "inf");
	tc_snprintf (buf, sizeof(buf), "%g", myf->unknownDiff);
	optstr_param (options, "unknowndiff", "Maximum inter-frame change vs. detail differences for neglecting interlaced video", "%f", buf, "1.0", "inf");
	tc_snprintf (buf, sizeof(buf), "%g", myf->progressiveDiff);
	optstr_param (options, "progressivediff", "Minimum inter-frame change vs. detail differences for detecting progressive video" ,"%f", buf, "unknowndiff", "inf");
	tc_snprintf (buf, sizeof(buf), "%g", myf->progressiveChange);
	optstr_param (options, "progressivechange", "Minimum temporal change needed for detecting progressive video" ,"%f", buf, "0", "inf");
	tc_snprintf (buf, sizeof(buf), "%g", myf->changedIfMore);
	optstr_param (options, "changedifmore", "Minimum temporal change for detecting truly changed frames" ,"%f", buf, "0", "65025");
	tc_snprintf (buf, sizeof(buf), "%d", myf->forceTelecineDetect);
	optstr_param (options, "forcetelecinedetect", "Detect telecine even on non-NTSC (29.97fps) video", "%d", buf, "0", "1");
	tc_snprintf (buf, sizeof(buf), "%d", myf->verbose);
	optstr_param (options, "verbose", "Output analysis for every frame", "%d", buf, "0", "2");
	tc_snprintf (buf, sizeof(buf), "%d", myf->outDiff);
	optstr_param (options, "outdiff", "Output internal debug frames as luminance of YUV video (see source)", "%d", buf, "0", "11");
    }

    /*
     * filter frame routine
     */
    /* need to process frames in-order */
    if ((ptr->tag & TC_PRE_S_PROCESS) && (ptr->tag & TC_VIDEO)) {

	uint8_t *tmp;
	int i, j;

	assert (ptr->free == 0 || ptr->free == 1);
	assert (ptr->video_buf_Y[!ptr->free] == ptr->video_buf);

	/* Convert / Copy to luminance only */
	switch (myf->codec) {
	case TC_CODEC_RGB24:
	    tcv_convert(myf->tcvhandle, ptr->video_buf, myf->lumIn,
			myf->width, myf->height, IMG_RGB_DEFAULT, IMG_Y8);
	    break;
	case TC_CODEC_YUY2:
	    tcv_convert(myf->tcvhandle, ptr->video_buf, myf->lumIn,
			myf->width, myf->height, IMG_YUY2, IMG_Y8);
	    break;
	case TC_CODEC_YUV420P:
	    tcv_convert(myf->tcvhandle, ptr->video_buf, myf->lumIn,
			myf->width, myf->height, IMG_YUV_DEFAULT, IMG_Y8);
	    break;
	case TC_CODEC_YUV422P:
	    tcv_convert(myf->tcvhandle, ptr->video_buf, myf->lumIn,
			myf->width, myf->height, IMG_YUV422P, IMG_Y8);
	    break;
	default:
	    assert (0);
	}

	/* Bob Top field */
	bob_field (myf->lumIn, myf->lumInT, myf->width, myf->height/2-1);
	/* Bob Bottom field */
	ac_memcpy (myf->lumInB, myf->lumIn + myf->width, myf->width);
	bob_field (myf->lumIn + myf->width, myf->lumInB + myf->width,
	           myf->width, myf->height/2-1);
	/* last copied line is ignored, buffer is large enough */

	if (myf->numFrames == 0)
	    myf->numFrames++;
	else if (! (ptr->tag & TC_FRAME_IS_SKIPPED)) {
	    /* check_it */
	    check_interlace (myf, ptr->id);
	}

	/* only works with YUV data correctly */
	switch (myf->outDiff) {
	case 1:				/* lumIn */
	    ac_memcpy (ptr->video_buf, myf->lumIn, myf->size);
	    break;
	case 2:				/* field shift */
	    for (i = 0 ; i < myf->height-2; i += 2)
		for (j = 0; j < myf->width; j++) {
		    ptr->video_buf [myf->width*i+j] =
			myf->lumIn [myf->width*i+j];
		    ptr->video_buf [myf->width*(i+1)+j] =
			myf->lumPrev [myf->width*(i+1)+j];
		}
	    break;
	case 3:				/* lumInT */
	    ac_memcpy (ptr->video_buf, myf->lumInT, myf->size);
	    break;
	case 4:				/* lumInB */
	    ac_memcpy (ptr->video_buf, myf->lumInB, myf->size);
	    break;
	case 5:				/* lumPrevT */
	    ac_memcpy (ptr->video_buf, myf->lumPrevT, myf->size);
	    break;
	case 6:				/* lumPrevB */
	    ac_memcpy (ptr->video_buf, myf->lumPrevB, myf->size);
	    break;
	case 7:				/* pixDiff */
	    pic_diff (myf->lumInT, myf->lumInB,   ptr->video_buf, myf->size,4);
	    break;
	case 8:				/* pixShiftChangedT */
	    pic_diff (myf->lumInT, myf->lumPrevB, ptr->video_buf, myf->size,4);
	    break;
	case 9:				/* pixShiftChangedB */
	    pic_diff (myf->lumInB, myf->lumPrevT, ptr->video_buf, myf->size,4);
	    break;
	case 10:			/* pixLastT */
	    pic_diff (myf->lumInT, myf->lumPrevT, ptr->video_buf, myf->size,4);
	    break;
	case 11:			/* pixLastB */
	    pic_diff (myf->lumInB, myf->lumPrevB, ptr->video_buf, myf->size,4);
	    break;
	}

	/* The current frame gets the next previous frame :-P */
	tmp = myf->lumPrev;   myf->lumPrev  = myf->lumIn;   myf->lumIn  = tmp;
	tmp = myf->lumPrevT;  myf->lumPrevT = myf->lumInT;  myf->lumInT = tmp;
	tmp = myf->lumPrevB;  myf->lumPrevB = myf->lumInB;  myf->lumInB = tmp;
    }

    return 0;
}
Exemplo n.º 10
0
static int encoder_acquire_vframe(TCEncoderBuffer *buf, vob_t *vob)
{
    int got_frame = TC_TRUE;

    do {
        buf->vptr = vframe_retrieve();
        if (!buf->vptr) {
            if (verbose >= TC_THREADS)
                tc_log_msg(__FILE__, "frame retrieve interrupted!");
            return -1; /* can't acquire video frame */
        }
        got_frame = TC_TRUE;
        buf->frame_id = buf->vptr->id + tc_get_frames_skipped_cloned();

        if (verbose & TC_STATS) {
            tc_log_info(__FILE__, "got frame %p (id=%i)",
                                  buf->vptr, buf->frame_id);
        }

        /*
         * now we do the post processing ... this way, if just a video frame is
         * skipped, we'll know.
         *
         * we have to check to make sure that before we do any processing
         * that this frame isn't out of range (if it is, and one is using
         * the "-t" split option, we'll see this frame again.
         */
        apply_video_filters(buf->vptr, vob);

        if (buf->vptr->attributes & TC_FRAME_IS_SKIPPED) {
            if (buf->vptr != NULL
              && (buf->vptr->attributes & TC_FRAME_WAS_CLONED)
            ) {
                /* XXX do we want to track skipped cloned flags? */
                tc_update_frames_cloned(1);
            }

            if (buf->vptr != NULL
              && (buf->vptr->attributes & TC_FRAME_IS_CLONED)
            ) {
                /* XXX what to do when a frame is cloned and skipped? */
                /*
                 * I'd like to say they cancel, but perhaps they will end
                 * up also skipping the clone?  or perhaps they'll keep,
                 * but modify the clone?  Best to do the whole drill :/
                 */
                if (verbose & TC_DEBUG) {
                    tc_log_info (__FILE__, "(%i) V pointer done. "
                                           "Skipped and Cloned: (%i)",
                                           buf->vptr->id,
                                           (buf->vptr->attributes));
                }

                /* update flags */
                buf->vptr->attributes &= ~TC_FRAME_IS_CLONED;
                buf->vptr->attributes |= TC_FRAME_WAS_CLONED;
                /*
                 * this has to be done here,
                 * frame_threads.c won't see the frame again
                 */
            }
            if (buf->vptr != NULL
              && !(buf->vptr->attributes & TC_FRAME_IS_CLONED)
            ) {
                vframe_remove(buf->vptr);
                /* reset pointer for next retrieve */
                buf->vptr = NULL;
            }
            // tc_update_frames_skipped(1);
            got_frame = TC_FALSE;
        }
    } while (!got_frame);

    return 0;
}
Exemplo n.º 11
0
static int
connect_to_server(tc_event_loop_t *event_loop)
{
    int                    i, j, fd;
    uint32_t               target_ip;
    uint16_t               target_port;
    connections_t         *connections;

    /* 
     * add connections to the real servers for sending router info 
     * and receiving response packet
     */
    for (i = 0; i < clt_settings.real_servers.num; i++) {

        target_ip = clt_settings.real_servers.ips[i];
        target_port = clt_settings.real_servers.ports[i];
        if (target_port == 0) {
            target_port = clt_settings.srv_port;
        }

        if (clt_settings.real_servers.active[i] != 0) {
            continue;
        }

        connections = &(clt_settings.real_servers.connections[i]);
        for (j = 0; j < connections->num; j++) {
            fd = connections->fds[j];
            if (fd > 0) {
                tc_log_info(LOG_NOTICE, 0, "it close socket:%d", fd);
                tc_socket_close(fd);
                tc_event_del(clt_settings.ev[fd]->loop, 
                        clt_settings.ev[fd], TC_EVENT_READ);
                tc_event_destroy(clt_settings.ev[fd]);
                connections->fds[j] = -1;
            }
        }

        clt_settings.real_servers.connections[i].num = 0;
        clt_settings.real_servers.connections[i].remained_num = 0;

        for (j = 0; j < clt_settings.par_connections; j++) {
            fd = tc_message_init(event_loop, target_ip, target_port);
            if (fd == TC_INVALID_SOCKET) {
                return TC_ERROR;
            }

            if (!send_version(fd)) {
                return TC_ERROR;
            }

            if (j == 0) {
                clt_settings.real_servers.active_num++;
                clt_settings.real_servers.active[i] = 1;
            }

            clt_settings.real_servers.connections[i].fds[j] = fd;
            clt_settings.real_servers.connections[i].num++;
            clt_settings.real_servers.connections[i].remained_num++;

        }

        tc_log_info(LOG_NOTICE, 0, "add dr tunnels for exchanging info:%u:%u",
                target_ip, target_port);
    }

    return TC_OK;


}
Exemplo n.º 12
0
int tc_filter(frame_list_t *ptr_, char *options)
{
  aframe_list_t *ptr = (aframe_list_t *)ptr_;
  int n;
  double sum;

  short *s;

  vob_t *vob=NULL;

  if(ptr->tag & TC_FILTER_GET_CONFIG) {
      optstr_filter_desc (options, MOD_NAME, MOD_CAP, MOD_VERSION, "Thomas Oestreich", "AE", "1");
      optstr_param (options, "level", "The audio must be under this level to be skipped", "%d", "10", "0", "255");
      optstr_param (options, "range", "Number of samples over level will be keyframes", "%d", "25", "0", "255");
      return 0;
  }

  //----------------------------------
  //
  // filter init
  //
  //----------------------------------

  if(ptr->tag & TC_FILTER_INIT) {

    if((vob = tc_get_vob())==NULL) return(-1);

    // filter init ok.

    if(verbose) tc_log_info(MOD_NAME, "%s %s", MOD_VERSION, MOD_CAP);

    if(verbose) tc_log_info(MOD_NAME, "options=%s", options);

    if(options!=NULL) {
	if (!is_optstr(options)) {
	    n=sscanf(options,"%d:%d", &level, &range);
	} else {
	    optstr_get (options, "level", "%d", &level);
	    optstr_get (options, "range", "%d", &range);
	}
    }

    range_ctr=range;

    return(0);
  }

  //----------------------------------
  //
  // filter close
  //
  //----------------------------------

  if(ptr->tag & TC_FILTER_CLOSE) {

    return(0);
  }

  //----------------------------------
  //
  // filter frame routine
  //
  //----------------------------------

  if(verbose & TC_STATS)
    tc_log_info(MOD_NAME, "%s/%s %s %s",
                vob->mod_path, MOD_NAME, MOD_VERSION, MOD_CAP);

  // tag variable indicates, if we are called before
  // transcodes internal video/audo frame processing routines
  // or after and determines video/audio context

  if(ptr->tag & TC_PRE_S_PROCESS && ptr->tag & TC_AUDIO && !(ptr->attributes & TC_FRAME_IS_SKIPPED)) {

    total += (uint64_t) ptr->audio_size;

    s=(short *) ptr->audio_buf;

    sum=0;

    for(n=0; n<ptr->audio_size>>1; ++n) {
      sum+=(double) ((int)(*s) * (int)(*s));
      s++;
    }

    if(ptr->audio_size>0) sum = sqrt(sum)/(ptr->audio_size>>1);

    sum *= 1000;

    if(verbose & TC_DEBUG) tc_log_info(MOD_NAME, "frame=%d sum=%f", ptr->id, sum);

    if(sum<level) {

      if(range_ctr == range) {

	ptr->attributes |= TC_FRAME_IS_SKIPPED;
	skip_mode=1;
      } else ++range_ctr;

    } else {

      if(skip_mode) ptr->attributes |= TC_FRAME_IS_KEYFRAME;
      skip_mode = 0;
      range_ctr = 0;
    }
  }
static int 
prepare_for_renew_session(tc_sess_t *s, tc_iph_t *ip, tc_tcph_t *tcp)
{
    uint16_t            size_ip;
    uint32_t            tot_clen, base_seq;
    tc_iph_t           *fir_ip, *t_ip;
    tc_tcph_t          *fir_tcp, *t_tcp;
    p_link_node         ln;
    unsigned char      *p;
    mysql_table_item_t *item;
    tc_mysql_session   *mysql_sess;

    if (!ctx.fir_auth_pack) {
        tc_log_info(LOG_WARN, 0, "no first auth pack here");
        return TC_ERR;
    }

    mysql_sess = s->data;
    if (mysql_sess == NULL) {
        tc_log_info(LOG_WARN, 0, "mysql session structure is not allocated");
        return TC_ERR;
    } else if (mysql_sess->fir_auth_added) {
        tc_log_info(LOG_NOTICE, 0, "dup visit prepare_for_renew_session");
        return TC_OK;
    }

    s->sm.need_rep_greet = 1;

    fir_ip        = ctx.fir_auth_pack;
    fir_ip->saddr = ip->saddr;
    size_ip       = fir_ip->ihl << 2;
    fir_tcp = (tc_tcph_t *) ((char *) fir_ip + size_ip);
    fir_tcp->source = tcp->source;

    tot_clen = ctx.fir_auth_cont_len;

    item = hash_find(ctx.table, s->hash_key);
    if (item) {
        tot_clen += item->tot_cont_len;
    }

    tc_log_debug2(LOG_INFO, 0, "total len subtracted:%u,p:%u", tot_clen, 
            ntohs(s->src_port));

    tcp->seq     = htonl(ntohl(tcp->seq) - tot_clen);
    fir_tcp->seq = htonl(ntohl(tcp->seq) + 1);
    tc_save_pack(s, s->slide_win_packs, fir_ip, fir_tcp);  
    mysql_sess->fir_auth_added = 1;

    base_seq = ntohl(fir_tcp->seq) + ctx.fir_auth_cont_len;

    if (item) {
        ln = link_list_first(item->list); 
        while (ln) {
            p = (unsigned char *) ln->data;
            t_ip  = (tc_iph_t *) (p + ETHERNET_HDR_LEN);
            t_tcp = (tc_tcph_t *) ((char *) t_ip + size_ip);
            t_tcp->seq = htonl(base_seq);
            tc_save_pack(s, s->slide_win_packs, t_ip, t_tcp);  
            base_seq += TCP_PAYLOAD_LENGTH(t_ip, t_tcp);
            ln = link_list_get_next(item->list, ln);
        }
    }

    mysql_sess->old_ps_cleaned = 0;

    return TC_OK;
}
Exemplo n.º 14
0
static int faac_configure(TCModuleInstance *self,
                          const char *options, vob_t *vob)
{
    PrivateData *pd;
    int samplerate = vob->mp3frequency ? vob->mp3frequency : vob->a_rate;
    int ret;
    unsigned long dummy;
    faacEncConfiguration conf;

    TC_MODULE_SELF_CHECK(self, "configure");

    pd = self->userdata;

    /* Save bytes per sample */
    pd->bps = (vob->dm_chan * vob->dm_bits) / 8;

    /* Create FAAC handle (freeing any old one that might be left over) */
    if (pd->handle)
        faacEncClose(pd->handle);
    pd->handle = faacEncOpen(samplerate, vob->dm_chan, &pd->framesize, &dummy);
    if (!pd->handle) {
        tc_log_error(MOD_NAME, "FAAC initialization failed");
        return TC_ERROR;
    }

    /* Set up our default audio parameters */
    /* why can't just use a pointer here? -- FR */
    /* Because the function returns a pointer to an internal buffer  --AC */
    conf = *faacEncGetCurrentConfiguration(pd->handle);
    conf.mpegVersion = MPEG4;
    conf.aacObjectType = MAIN;
    conf.allowMidside = 1;
    conf.useLfe = 0;
    conf.useTns = 1;
    conf.bitRate = vob->mp3bitrate / vob->dm_chan;
    conf.bandWidth = 0;  // automatic configuration
    conf.quantqual = 100;  // FIXME: quality should be a per-module setting
    conf.outputFormat = 1;
    if (vob->dm_bits != 16) {
        tc_log_error(MOD_NAME, "Only 16-bit samples supported");
        return TC_ERROR;
    }
    conf.inputFormat = FAAC_INPUT_16BIT;
    conf.shortctl = SHORTCTL_NORMAL;

    ret = optstr_get(options, "quality", "%li", &conf.quantqual);
    if (ret >= 0) {
        if (verbose >= TC_INFO) {
            tc_log_info(MOD_NAME, "using quality=%li", conf.quantqual);
        }
    }

    if (!faacEncSetConfiguration(pd->handle, &conf)) {
        tc_log_error(MOD_NAME, "Failed to set FAAC configuration");
        faacEncClose(pd->handle);
        pd->handle = 0;
        return TC_ERROR;
    }

    /* Allocate local audio buffer */
    if (pd->audiobuf)
        free(pd->audiobuf);
    pd->audiobuf = tc_malloc(pd->framesize * pd->bps);
    if (!pd->audiobuf) {
        tc_log_error(MOD_NAME, "Unable to allocate audio buffer");
        faacEncClose(pd->handle);
        pd->handle = 0;
        return TC_ERROR;
    }

    return TC_OK;
}
Exemplo n.º 15
0
static int
set_details()
{

    clt_settings.session_keepalive_timeout = clt_settings.session_timeout;
    tc_log_info(LOG_NOTICE, 0, "keepalive timeout:%d",
                clt_settings.session_keepalive_timeout);

    if (clt_settings.users <= 0) {
        tc_log_info(LOG_ERR, 0, "please set the -u parameter");
        return -1;
    }

    if (clt_settings.raw_clt_ips == NULL) {
        tc_log_info(LOG_ERR, 0, "please set the -c parameter");
        return -1;
    }
    retrieve_client_ips();

    /* set the ip port pair mapping according to settings */
    if (retrieve_target_addresses(clt_settings.raw_transfer,
                                  &clt_settings.transfer) == -1)
    {
        return -1;
    }

    if (clt_settings.par_connections <= 0) {
        clt_settings.par_connections = 1;
    } else if (clt_settings.par_connections > MAX_CONNECTION_NUM) {
        clt_settings.par_connections = MAX_CONNECTION_NUM;
    }
    tc_log_info(LOG_NOTICE, 0, "parallel connections per target:%d",
                clt_settings.par_connections);

    if (clt_settings.raw_pcap_files == NULL) {
        tc_log_info(LOG_ERR, 0, "it must have -f argument for gryphon");
        fprintf(stderr, "no -f argument\n");
        return -1;
    }

    retrieve_pcap_files();

    if (clt_settings.throughput_factor < 1) {
        clt_settings.throughput_factor = 1;
    }

    tc_log_info(LOG_NOTICE, 0, "throughput factor: %d,interval:%llu ms",
                clt_settings.throughput_factor, clt_settings.interval);

    if (clt_settings.interval > 0) {
        clt_settings.interval = clt_settings.interval * 1000;
    }

#if (GRYPHON_PCAP_SEND)
    if (clt_settings.output_if_name != NULL) {
        tc_log_info(LOG_NOTICE, 0, "output device:%s",
                    clt_settings.output_if_name);
    } else {
        tc_log_info(LOG_ERR, 0, "output device is null");
        return -1;
    }
#endif

    /* retrieve real server ip addresses  */
    if (clt_settings.raw_rs_list != NULL) {
        tc_log_info(LOG_NOTICE, 0, "s parameter:%s",
                    clt_settings.raw_rs_list);
        retrieve_real_servers();
    } else {
        tc_log_info(LOG_WARN, 0, "no real server ip addresses");
        return -1;
    }

    /* daemonize */
    if (clt_settings.do_daemonize) {
        if (sigignore(SIGHUP) == -1) {
            tc_log_info(LOG_ERR, errno, "Failed to ignore SIGHUP");
        }
        if (daemonize() == -1) {
            fprintf(stderr, "failed to daemonize() in order to daemonize\n");
            return -1;
        }
    }

    return 0;
}
Exemplo n.º 16
0
void
router_update(int old, int main_router_fd, tc_ip_header_t *ip_header)
{
#if (!TCPCOPY_SINGLE)
    int                     fd;
    uint32_t                key;
#endif
    uint32_t                size_ip, size_tcp, tot_len;
    msg_server_t            msg;
    tc_tcp_header_t        *tcp_header;
#if (TCPCOPY_MYSQL_ADVANCED)
    uint32_t                cont_len;
    unsigned char          *payload, *p;
#endif
#if (TCPCOPY_SINGLE)
    if (main_router_fd == 0) {
        return;
    }
#endif
    if (ip_header->protocol != IPPROTO_TCP) {
        tc_log_info(LOG_INFO, 0, "this is not a tcp packet");
        return;
    }

    size_ip = ip_header->ihl << 2;
    tcp_header = (tc_tcp_header_t *) ((char *) ip_header + size_ip);
    size_tcp = tcp_header->doff << 2;
    tot_len  = ntohs(ip_header->tot_len);

    memset(&msg, 0, sizeof(struct msg_server_s));
    memcpy((void *) &(msg.ip_header), ip_header, sizeof(tc_ip_header_t));
    memcpy((void *) &(msg.tcp_header), tcp_header, size_tcp);

#if (TCPCOPY_MYSQL_ADVANCED)
    cont_len = tot_len - size_ip - size_tcp;
    if (cont_len > 0) {
        payload = (unsigned char *) ((char *) tcp_header + size_tcp);
        if (cont_len <= MAX_PAYLOAD_LEN) {
            p = ((unsigned char *) &(msg.tcp_header)) + size_tcp;
            memcpy((void *) p, payload, cont_len);
        }
    }
#endif 
#if (!TCPCOPY_SINGLE)
    key = get_route_key(old, ip_header->daddr, tcp_header->dest, 
            ip_header->saddr, tcp_header->source);
    fd  = router_get(key);
    if (fd <= 0) {
        if (tcp_header->syn || tcp_header->rst) {
            if (tcp_header->rst) {
                tc_log_info(LOG_NOTICE, 0, "reset from tcp");
            } 
            tc_log_debug0(LOG_DEBUG, 0, "fd is null");
            delay_table_add(key, &msg);
            return ;
        } else {
            tc_log_info(LOG_NOTICE, 0, "fd is null after session is created");
            tc_log_trace(LOG_NOTICE, 0,  BACKEND_FLAG, ip_header, tcp_header);
            return;
        }
    }
#endif

    tc_log_debug_trace(LOG_NOTICE, 0,  BACKEND_FLAG, ip_header, tcp_header);

#if (INTERCEPT_COMBINED)

#if (!TCPCOPY_SINGLE)
    buffer_and_send(main_router_fd, (int) (long) fd, &msg);
#else
    buffer_and_send(main_router_fd, main_router_fd, &msg);
#endif                       
#else

#if (!TCPCOPY_SINGLE)
    tc_socket_send((int) (long) fd, (char *) &msg, MSG_SERVER_SIZE);
#else
    tc_socket_send(main_router_fd, (char *) &msg, MSG_SERVER_SIZE);
#endif

#endif

}
Exemplo n.º 17
0
/*
 * main entry point
 */
int
main(int argc, char **argv)
{
    int ret, is_continue = 1;

    settings_init();

#if (GRYPHON_SIGACTION)
    if (set_signal_handler(signals) == -1) {
        return -1;
    }
#else
    signal(SIGALRM, tc_time_sig_alarm);
    signal(SIGINT,  gryphon_over);
    signal(SIGPIPE, gryphon_over);
    signal(SIGHUP,  gryphon_over);
    signal(SIGTERM, gryphon_over);
#endif

    tc_time_init();

    if (read_args(argc, argv) == -1) {
        return -1;
    }

    if (clt_settings.log_path == NULL) {
        clt_settings.log_path = "error_gryphon.log";
    }

    if (tc_log_init(clt_settings.log_path) == -1) {
        return -1;
    }

    /* output debug info */
    output_for_debug(argc, argv);


    /* set details for running */
    if (set_details() == -1) {
        return -1;
    }

    if (set_timer() == -1) {
        return -1;
    }

    ret = tc_event_loop_init(&event_loop, MAX_FD_NUM);
    if (ret == TC_EVENT_ERROR) {
        tc_log_info(LOG_ERR, 0, "event loop init failed");
        is_continue = 0;
    }

    if (is_continue) {
        ret = tc_build_session_table(65536);
        if (ret == TC_ERROR) {
            is_continue = 0;
        } else {
            ret = gryphon_init(&event_loop);
            if (ret == TC_ERROR) {
                is_continue = 0;
            } else {
                if (!tc_build_users(clt_settings.client_mode,
                                    clt_settings.users, clt_settings.valid_ips,
                                    clt_settings.valid_ip_num))
                {
                    is_continue = 0;
                }
            }
        }
    }

    if (is_continue) {
        if (set_timer() == -1) {
            is_continue = 0;
        }
    }

    if (is_continue) {
        /* run now */
        tc_event_process_cycle(&event_loop);
    }

    gryphon_release_resources();

    return 0;
}
Exemplo n.º 18
0
static int
dispose_packet(unsigned char *frame, int frame_len, int ip_recv_len,
        int *p_valid_flag)
{
    int              replica_num, i, last, packet_num, max_payload,
                     index, payload_len;
    char             *p, buf[ETHERNET_HDR_LEN + IP_RECV_BUF_SIZE];
    bool             packet_valid = false;
    uint16_t         id, size_ip, size_tcp, tot_len, cont_len, 
                     pack_len = 0, head_len;
    uint32_t         seq;
    unsigned char   *packet;
    tc_ip_header_t  *ip_header;
    tc_tcp_header_t *tcp_header;

    packet = frame + ETHERNET_HDR_LEN;

    if (is_packet_needed(packet)) {

        replica_num = clt_settings.replica_num;
        ip_header   = (tc_ip_header_t *) packet;

        if (clt_settings.clt_tf_ip != 0) {
            ip_header->saddr = clt_settings.clt_tf_ip;
        }

        /* 
         * If the packet length is larger than MTU, we split it. 
         */
        if (ip_recv_len > clt_settings.mtu) {

            /* calculate number of packets */
            size_ip     = ip_header->ihl << 2;
            tot_len     = ntohs(ip_header -> tot_len);
            if (tot_len != ip_recv_len) {
                tc_log_info(LOG_WARN, 0, "packet len:%u, recv len:%u",
                            tot_len, ip_recv_len);
                return TC_ERROR;
            }

            tcp_header  = (tc_tcp_header_t *) ((char *) ip_header + size_ip);
            size_tcp    = tcp_header->doff << 2;
            cont_len    = tot_len - size_tcp - size_ip;
            head_len    = size_ip + size_tcp;
            max_payload = clt_settings.mtu - head_len;
            packet_num  = (cont_len + max_payload - 1)/max_payload;
            seq         = ntohl(tcp_header->seq);
            last        = packet_num - 1;
            id          = ip_header->id;

#if (TCPCOPY_DEBUG)
            tc_log_trace(LOG_NOTICE, 0, CLIENT_FLAG, ip_header, tcp_header);
#endif
            tc_log_debug1(LOG_DEBUG, 0, "recv:%d, more than MTU", ip_recv_len);
            index = head_len;

            for (i = 0 ; i < packet_num; i++) {
                tcp_header->seq = htonl(seq + i * max_payload);
                if (i != last) {
                    pack_len  = clt_settings.mtu;
                } else {
                    pack_len += (cont_len - packet_num * max_payload);
                }
                payload_len = pack_len - head_len;
                ip_header->tot_len = htons(pack_len);
                ip_header->id = id++;
                p = buf + ETHERNET_HDR_LEN;
                /* copy header here */
                memcpy(p, (char *) packet, head_len);
                p +=  head_len;
                /* copy payload here */
                memcpy(p, (char *) (packet + index), payload_len);
                index = index + payload_len;
                if (replica_num > 1) {
                    packet_valid = process_packet(true, (unsigned char *) buf,
                            ETHERNET_HDR_LEN + pack_len);
                    replicate_packs((unsigned char *) buf, 
                            ETHERNET_HDR_LEN + pack_len, replica_num);
                } else {
                    packet_valid = process_packet(false, (unsigned char *) buf,
                            ETHERNET_HDR_LEN + pack_len);
                }
            }
        } else {

            if (replica_num > 1) {

                packet_valid = process_packet(true, frame, frame_len);
                replicate_packs(frame, frame_len, replica_num);
            } else {

                packet_valid = process_packet(false, frame, frame_len);
            }
        }
    }

    if (p_valid_flag) {
        *p_valid_flag = (packet_valid == true ? 1 : 0);
    }

    return TC_OK;
}
Exemplo n.º 19
0
static
void put_resp_header_to_pool(tc_ip_header_t *ip_header)
{
    int                    *p_len, cur_w_pos, diff, next_w_pos;
    char                   *p_content;
    uint16_t                size_ip, save_len, record_len;
#if (TCPCOPY_MYSQL_ADVANCED) 
    uint16_t                size_tcp, cont_len, tot_len;
    unsigned char          *payload; 
#endif
    uint64_t                next_w_cnt; 
    tc_tcp_header_t        *tcp_header;

    if (ip_header->protocol != IPPROTO_TCP) {
        tc_log_info(LOG_WARN, 0, "this is not a tcp packet");
        return;
    }

    save_len = RESP_MAX_USEFUL_SIZE;

    size_ip = ip_header->ihl << 2;
    tcp_header = (tc_tcp_header_t *) ((char *)ip_header + size_ip);

#if (TCPCOPY_MYSQL_ADVANCED) 
    size_tcp = tcp_header->doff << 2;
    tot_len  = ntohs(ip_header->tot_len);
    cont_len = tot_len - size_ip - size_tcp;
    if (cont_len > 0 && cont_len <= MAX_PAYLOAD_LEN) {
            save_len += cont_len;
    }
#endif

    record_len = save_len;
    pthread_mutex_lock(&mutex);
    next_w_cnt = write_counter + save_len + sizeof(int); 
    next_w_pos = next_w_cnt & POOL_MASK;

    if (next_w_pos > POOL_MAX_ADDR) {
        next_w_cnt  = (next_w_cnt / POOL_SIZE + 1) << POOL_SHIFT;
        record_len += (POOL_SIZE - next_w_pos);
    }

    diff = next_w_cnt - read_counter;
    
    for (;;) {
        if (diff > POOL_SIZE) {
            tc_log_info(LOG_WARN, 0, "pool is full");
            pthread_cond_wait(&empty, &mutex);
        } else {
            break;
        }
        diff = next_w_cnt - read_counter;
    }

    cur_w_pos = write_counter & POOL_MASK;
    p_len     = (int *) (pool + cur_w_pos);
    p_content = (char *) ((unsigned char *) p_len + sizeof(int));
    
    write_counter = next_w_cnt;
    
    *p_len = record_len;
    ip_header->ihl = (sizeof(tc_ip_header_t)) >> 2;
    memcpy(p_content, ip_header, sizeof(tc_ip_header_t));
    p_content = p_content + sizeof(tc_ip_header_t);
    memcpy(p_content, tcp_header, sizeof(tc_tcp_header_t));

#if (TCPCOPY_MYSQL_ADVANCED) 
    if (cont_len > 0 && cont_len <= MAX_PAYLOAD_LEN) {
        p_content = p_content + sizeof(tc_tcp_header_t);
        payload = (unsigned char*) ((char*) tcp_header + size_tcp);
        memcpy(p_content, payload, cont_len);
    }
#endif

    pthread_cond_signal(&full);
    pthread_mutex_unlock(&mutex);
}
Exemplo n.º 20
0
static void 
send_packets_from_pcap(int first)
{
    int                 l2_len, ip_pack_len, p_valid_flag = 0;
    bool                stop;
    pcap_t             *pcap;
    unsigned char      *pkt_data, *frame, *ip_data;
    struct pcap_pkthdr  pkt_hdr;  

    pcap = clt_settings.pcap;

    if (pcap == NULL) {
        return;
    }

    gettimeofday(&cur_time, NULL);

    stop = check_read_stop();

    while (!stop) {

        pkt_data = (u_char *) pcap_next(pcap, &pkt_hdr);
        if (pkt_data != NULL) {

            if (pkt_hdr.caplen < pkt_hdr.len) {

                tc_log_info(LOG_WARN, 0, "truncated packets,drop");
            } else {

                ip_data = get_ip_data(clt_settings.pcap, pkt_data, 
                        pkt_hdr.len, &l2_len);
                if (l2_len < ETHERNET_HDR_LEN) {
                    tc_log_info(LOG_WARN, 0, "l2 len is %d", l2_len);
                    continue;
                }

                last_pack_time = pkt_hdr.ts;
                if (ip_data != NULL) {
                    clt_settings.pcap_time = last_pack_time.tv_sec * 1000 + 
                        last_pack_time.tv_usec / 1000; 

                    ip_pack_len = pkt_hdr.len - l2_len;
                    tc_log_debug2(LOG_DEBUG, 0, "frame len:%d, ip len:%d",
                            pkt_hdr.len, ip_pack_len);
                    frame = ip_data - ETHERNET_HDR_LEN;
                    dispose_packet(frame, ip_pack_len + ETHERNET_HDR_LEN,
                            ip_pack_len, &p_valid_flag);
                    if (p_valid_flag) {

                        tc_log_debug0(LOG_DEBUG, 0, "valid flag for packet");

                        if (first) {
                            first_pack_time = pkt_hdr.ts;
                            first = 0;
                        } else {
                            adj_v_pack_diff = timeval_diff(&last_v_pack_time,
                                    &last_pack_time);
                        }

                        /* set last valid packet time in pcap file */
                        last_v_pack_time = last_pack_time;

                        stop = check_read_stop();

                    } else {
                        tc_log_debug0(LOG_DEBUG, 0, "invalid flag");
                    }
                }
            }
        } else {

            tc_log_info(LOG_WARN, 0, "stop, null from pcap_next");
            stop = true;
            read_pcap_over = true;
            read_pcap_over_time = tc_time();
        }
    }
}
Exemplo n.º 21
0
static int
parse_options(char *options, int *pre, double *infps, double *outfps)
{
	char	*p, *pbase, *q, *r;
	size_t	len;
	vob_t	*vob;
	int	default_pre, i;

	/* defaults from -f and --export_fps */
	vob = tc_get_vob();
	if (!vob) return -1;
	*infps = vob->fps;
	*outfps = vob->ex_fps;
	default_pre = 1;

	if (!options || !*options) return 0;
	if (!strcmp(options, "help")) {
		tc_log_info(MOD_NAME, "(%s) help\n"
"This filter converts the video frame rate, by repeating or dropping frames.\n"
"options: <input fps>:<output fps>\n"
"example: -J fps=25:29.97 will convert from PAL to NTSC\n"
"In addition to the frame rate options, you may also specify pre or post.\n"
"If no rate options are given, defaults or -f/--export_fps/--export_frc will\n"
"be used.\n"
"If no pre or post options are given, decreasing rates will preprocess and\n"
"increasing rates will postprocess.\n"
			    , MOD_CAP);
		return -1;
	}

	len = strlen(options);
	p = pbase = malloc(len + 1);
	ac_memcpy(p, options, len);
	p[len] = '\0';

	i = 0;
	do {
		q = memchr(p, ':', len);
		if (q) *q++ = '\0';
		if (!strcmp(p, "pre")) {
			*pre = 1;
			default_pre = 0;
		} else if (!strncmp(p, "pre=", 4) && *(p + 4)) {
			*pre = strtol(p + 4, &r, 0);
			if (r == p) return -1;
			default_pre = 0;
		} else if (!strcmp(p, "post")) {
			*pre = 0;
			default_pre = 0;
		} else if (!strncmp(p, "post=", 5) && *(p + 5)) {
			*pre = !strtol(p + 4, &r, 0);
			if (r == p) return -1;
			default_pre = 0;
		} else {
			if (i == 0) {
				*infps = strtod(p, &r);
				if (r == p) return -1;
			} else if (i == 1) {
				*outfps = strtod(p, &r);
				if (r == p) return -1;
			} else return -1;
			i++;
		}
	} while (q && (p = q));

	free(pbase);

	if (default_pre) {
		if (*infps > *outfps) *pre = 1;
		else if (*infps < *outfps) *pre = 0;
	}

	return 0;
}
Exemplo n.º 22
0
static int resp_dispose(tc_ip_header_t *ip_header)
{
    int                  i, passed;
    uint16_t             port, size_ip, size_tcp, tot_len;
    uint32_t             ip_addr;
    ip_port_pair_t      *pair;
    tc_tcp_header_t     *tcp_header;

    if (ip_header->protocol != IPPROTO_TCP) {
        return TC_OK;
    }

    tot_resp_packs++;

    size_ip   = ip_header->ihl << 2;
    if (size_ip < 20) {
        tc_log_info(LOG_WARN, 0, "Invalid IP header length: %d", size_ip);
        return TC_OK;
    }

    tot_len   = ntohs(ip_header->tot_len);

    tcp_header = (tc_tcp_header_t *) ((char *) ip_header + size_ip);
    size_tcp   = tcp_header->doff << 2;
    if (size_tcp < 20) {
        tc_log_info(LOG_WARN, 0, "Invalid TCP header len: %d bytes,pack len:%d",
                size_tcp, tot_len);
        return TC_OK;
    }

#if (TCPCOPY_PCAP)
    if (srv_settings.user_filter != NULL) {
        passed = 1;
    } else {
        passed = 0;
    }
#else
    passed = 0;
#endif

    ip_addr = ip_header->saddr;
    port    = tcp_header->source;

    if (!passed) {
        /* filter the packets we do care about */
        for (i = 0; i < srv_settings.targets.num; i++) {
            pair = srv_settings.targets.mappings[i];
            if (ip_addr == pair->ip && port == pair->port) {
                passed = 1;
                break;
            } else if (0 == pair->ip && port == pair->port) {
                passed = 1;
                break;
            }
        }

        if (passed == 0) {
            return TC_OK;
        }
    }

    tot_copy_resp_packs++;

    router_update(srv_settings.old, ip_header);
    return TC_OK;

}
Exemplo n.º 23
0
static int  
set_details()
{
#if (INTERCEPT_ADVANCED && TCPCOPY_PCAP)
    int  len;
#endif

#if (!INTERCEPT_ADVANCED)
    /* retrieve ip address */
    if (srv_settings.raw_ip_list != NULL) {
        tc_log_info(LOG_NOTICE, 0, "-x parameter:%s", 
                srv_settings.raw_ip_list);
        retrieve_ip_addr();
    }
#endif
    
#if (INTERCEPT_ADVANCED)
    if (srv_settings.raw_targets != NULL) {
        tc_log_info(LOG_NOTICE, 0, "-o parameter:%s", 
                srv_settings.raw_targets);
        retrieve_target_addresses(srv_settings.raw_targets,
                &(srv_settings.targets));
    } else {
#if (!TCPCOPY_PCAP)
        tc_log_info(LOG_WARN, 0, "no raw targets for advanced mode");
        return -1;
#else
        tc_log_info(LOG_NOTICE, 0, "no raw targets for advanced mode");
#endif
    }

#if (TCPCOPY_PCAP)
    if (srv_settings.raw_device != NULL) {
        tc_log_info(LOG_NOTICE, 0, "device:%s", srv_settings.raw_device);
        if (strcmp(srv_settings.raw_device, DEFAULT_DEVICE) == 0) {
            srv_settings.raw_device = NULL; 
        } else {
            retrieve_devices(srv_settings.raw_device, &(srv_settings.devices));
        }
    }

    if (srv_settings.user_filter != NULL) {
        tc_log_info(LOG_NOTICE, 0, "user filter:%s", srv_settings.user_filter);
        len = strlen(srv_settings.user_filter);
        if (len >= MAX_FILTER_LENGH) {
            tc_log_info(LOG_ERR, 0, "user filter is too long");
            return -1;
        }
        memcpy(srv_settings.filter, srv_settings.user_filter, len);
    } else {
        extract_filter();
    }
#endif

#endif

#if (INTERCEPT_NFQUEUE)
    if (srv_settings.max_queue_len <= 1024) {
        srv_settings.max_queue_len = -1;
    }
#endif

    /* daemonize */
    if (srv_settings.do_daemonize) {
        if (sigignore(SIGHUP) == -1) {
            tc_log_info(LOG_ERR, errno, "failed to ignore SIGHUP");
        }
        if (daemonize() == -1) {
            fprintf(stderr, "failed to daemonize() in order to daemonize\n");
            return -1;
        }
    }

    return 0;
}
Exemplo n.º 24
0
/* sniff response packets in the second test machine */
static int
sniff_init(tc_event_loop_t *event_loop)
{
#if (TCPCOPY_PCAP)
    int         i = 0;
    bool        work = false;
    char        ebuf[PCAP_ERRBUF_SIZE];
    devices_t  *devices;
    pcap_if_t  *alldevs, *d;
#else
   
    int fd;
    tc_event_t *ev;
#endif


#if (TCPCOPY_PCAP)
    devices = &(srv_settings.devices);
    if (srv_settings.raw_device == NULL) {
        if (pcap_findalldevs(&alldevs, ebuf) == -1) {
            tc_log_info(LOG_ERR, 0, "error in pcap_findalldevs:%s", ebuf);
            return TC_ERROR;
        }
        for (d = alldevs; d; d = d->next)
        {
            if (strcmp(d->name, DEFAULT_DEVICE) == 0) {
                continue;
            }

            if (i >= MAX_DEVICE_NUM) {
                pcap_freealldevs(alldevs);
                tc_log_info(LOG_ERR, 0, "It has too many devices");
                return TC_ERROR;
            }

            strcpy(devices->device[i++].name, d->name);
        }
        devices->device_num = i;

        pcap_freealldevs(alldevs);
    }

    for (i = 0; i < devices->device_num; i++) {
        if (tc_device_set(event_loop, &(devices->device[i]))
                == TC_ERROR) 
        {
            tc_log_info(LOG_WARN, 0, "device could not work:%s", 
                    devices->device[i].name);
        } else {
            work = true;
        }
    }

    if (!work) {
        tc_log_info(LOG_ERR, 0, "no device available for snooping packets");
        return TC_ERROR;
    }
#else
    if ((fd = tc_raw_socket_in_init(COPY_FROM_LINK_LAYER)) 
            == TC_INVALID_SOCKET) 
    {
        return TC_ERROR;
    }
    tc_socket_set_nonblocking(fd);

    ev = tc_event_create(fd, tc_process_resp_packet, NULL);
    if (ev == NULL) {
        return TC_ERROR;
    }

    if (tc_event_add(event_loop, ev, TC_EVENT_READ) == TC_EVENT_ERROR) {
        tc_log_info(LOG_ERR, 0, "add socket(%d) to event loop failed.", fd);
        return TC_ERROR;
    }
#endif

    return TC_OK;

}
Exemplo n.º 25
0
/* Initiate tcpcopy client */
int
tcp_copy_init(tc_event_loop_t *event_loop)
{
    int                      i;
#if (TCPCOPY_OFFLINE)
    char                    *pcap_file, ebuf[PCAP_ERRBUF_SIZE];
#endif
    uint16_t                 online_port, target_port;
    uint32_t                 target_ip;
    tc_event_t              *raw_socket_event;
    ip_port_pair_mapping_t  *pair, **mappings;

    /* keep it temporarily */
    select_server_set_callback(dispose_event);

    /* Register a timer to check resource every minute */
    tc_event_timer_add(event_loop, 60000, check_resource_usage);

    /* Init session table*/
    init_for_sessions();
    localhost = inet_addr("127.0.0.1");

    /* Init output raw socket info */
    send_init();

    /* Add connections to the tested server for exchanging info */
    mappings = clt_settings.transfer.mappings;
    for (i = 0; i < clt_settings.transfer.num; i++) {

        pair = mappings[i];
        online_port = pair->online_port;
        target_ip   = pair->target_ip;
        target_port = pair->target_port;
        if (address_add_msg_conn(event_loop, online_port, target_ip,
                                 clt_settings.srv_port))
        {
            return FAILURE;
        }
        tc_log_info(LOG_NOTICE, 0, "add a tunnel for exchanging info:%u",
                    ntohs(target_port));
    }

#if (!TCPCOPY_OFFLINE)
    /* Init input raw socket info */
    raw_sock = init_input_raw_socket();
#endif
    if (raw_sock != -1) {

        /* Add the input raw socket to select */
        raw_socket_event = tc_event_create(raw_sock, dispose_event_wrapper,
                                           NULL);
        if (raw_socket_event == NULL) {
            return FAILURE;
        }

        if (tc_event_add(event_loop, raw_socket_event, TC_EVENT_READ)
                == TC_EVENT_ERROR)
        {
            tc_log_info(LOG_ERR, 0, "add raw socket(%d) to event loop failed.",
                        raw_socket_event->fd);
            return FAILURE;
        }

        /* Init output raw socket info */
        send_init();

        /* Add connections to the tested server for exchanging info */
        mappings = clt_settings.transfer.mappings;
        for (i = 0; i < clt_settings.transfer.num; i++) {

            pair = mappings[i];
            online_port = pair->online_port;
            target_ip   = pair->target_ip;
            target_port = pair->target_port;

            if (address_add_msg_conn(event_loop, online_port, target_ip,
                                     clt_settings.srv_port) == -1)
            {
                return FAILURE;
            }

            tc_log_info(LOG_NOTICE, 0, "add a tunnel for exchanging info:%u",
                        ntohs(target_port));
        }

        return SUCCESS;
    } else {

#if (TCPCOPY_OFFLINE)
        select_offline_set_callback(send_packets_from_pcap);

        pcap_file = clt_settings.pcap_file;
        if (pcap_file != NULL) {

            if ((pcap = pcap_open_offline(pcap_file, ebuf)) == NULL) {
                tc_log_info(LOG_ERR, 0, "open %s" , ebuf);
                fprintf(stderr, "open %s\n", ebuf);
                return FAILURE;

            } else {

                gettimeofday(&base_time, NULL);
                tc_log_info(LOG_NOTICE, 0, "open pcap success:%s", pcap_file);
                tc_log_info(LOG_NOTICE, 0, "send the first packets here");
                send_packets_from_pcap(1);
            }
        } else {
            return FAILURE;
        }
#else
        return FAILURE;
#endif
    }

    return SUCCESS;
}
Exemplo n.º 26
0
static int 
tc_msg_event_process(tc_event_t *rev)
{
    int             fd, version;
    msg_client_t    msg;
    tunnel_basic_t *tunnel;

    fd = rev->fd;
    tunnel = srv_settings.tunnel;

    if (tunnel[fd].first_in) {
        if (tc_socket_recv(fd, (char *) &msg, MSG_CLIENT_MIN_SIZE) == 
                TC_ERROR) 
        {
            tc_intercept_release_tunnel(fd, rev);
            return TC_ERROR;
        }

        tunnel[fd].first_in = 0;

        version = ntohs(msg.type);
        if (msg.client_ip != 0 || msg.client_port != 0) {
            tunnel[fd].clt_msg_size = MSG_CLIENT_MIN_SIZE;
            srv_settings.old = 1;
            tc_log_info(LOG_WARN, 0, "client too old for intercept");
        } else {
            if (version != INTERNAL_VERSION) {
                tc_log_info(LOG_WARN, 0, 
                        "not compatible,tcpcopy:%d,intercept:%d",
                        msg.type, INTERNAL_VERSION);
            }
            tunnel[fd].clt_msg_size = MSG_CLIENT_SIZE;
            if (tc_socket_recv(fd, ((char *) &msg + MSG_CLIENT_MIN_SIZE), 
                        MSG_CLIENT_SIZE - MSG_CLIENT_MIN_SIZE) == TC_ERROR) 
            {
                tc_intercept_release_tunnel(fd, rev);
                return TC_ERROR;
            }
            return TC_OK;
        }

    } else {
        if (tc_socket_recv(fd, (char *) &msg, tunnel[fd].clt_msg_size) == 
                TC_ERROR) 
        {
            tc_intercept_release_tunnel(fd, rev);
            return TC_ERROR;
        }
    }

    msg.client_ip = msg.client_ip;
    msg.client_port = msg.client_port;
    msg.type = ntohs(msg.type);
    msg.target_ip = msg.target_ip;
    msg.target_port = msg.target_port;

    switch (msg.type) {
        case CLIENT_ADD:
#if (!TCPCOPY_SINGLE)
            tot_router_items++;
            tc_log_debug1(LOG_DEBUG, 0, "add client router:%u",
                    ntohs(msg.client_port));
            router_add(srv_settings.old, msg.client_ip, msg.client_port, 
                    msg.target_ip,  msg.target_port, rev->fd);
#endif
            break;
        case CLIENT_DEL:
            tc_log_debug1(LOG_DEBUG, 0, "del client router:%u",
                    ntohs(msg.client_port));
            break;
        default:
            tc_log_info(LOG_WARN, 0, "unknown msg type:%u", msg.type);
    }

    return TC_OK;
}
Exemplo n.º 27
0
static void
output_for_debug()
{
    /* print out version info */
    tc_log_info(LOG_NOTICE, 0, "tcpcopy version:%s", VERSION);
    tc_log_info(LOG_NOTICE, 0, "tcpcopy internal version:%d", 
            INTERNAL_VERSION);

    /* print out target info */
    tc_log_info(LOG_NOTICE, 0, "target:%s", clt_settings.raw_tf);

    /* print out working mode info */
#if (TC_OFFLINE)
    tc_log_info(LOG_NOTICE, 0, "TC_OFFLINE mode");
#endif
#if (TC_PCAP)
    tc_log_info(LOG_NOTICE, 0, "TC_PCAP mode");
#endif
#if (TC_SINGLE)
    tc_log_info(LOG_NOTICE, 0, "TC_SINGLE mode");
#endif
#if (TC_UDP)
    tc_log_info(LOG_NOTICE, 0, "TC_UDP mode");
#endif
#if (TC_COMBINED)
    tc_log_info(LOG_NOTICE, 0, "TC_COMBINED mode");
#endif
#if (TC_PCAP_SND)
    tc_log_info(LOG_NOTICE, 0, "TC_PCAP_SND mode");
#endif
#if (TC_MILLION_SUPPORT)
    tc_log_info(LOG_NOTICE, 0, "TC_MILLION_SUPPORT mode");
#endif
#if (TC_PLUGIN)
    tc_log_info(LOG_NOTICE, 0, "TC_PLUGIN mode");
#endif
#if (TC_PAYLOAD)
    tc_log_info(LOG_NOTICE, 0, "TC_PAYLOAD is true");
#endif
#if (TC_HAVE_EPOLL)
    tc_log_info(LOG_NOTICE, 0, "epoll mode");
#endif
#if (TC_HAVE_PF_RING)
    tc_log_info(LOG_NOTICE, 0, "TC_HAVE_PF_RING is true");
#endif
#if (TC_DETECT_MEMORY)
    tc_log_info(LOG_NOTICE, 0, "TC_DETECT_MEMORY is true");
#endif
}
Exemplo n.º 28
0
int 
tc_nfq_socket_init(struct nfq_handle **h, struct nfq_q_handle **qh,
        nfq_callback *cb, int max_queue_len)
{
    int fd;

    tc_log_info(LOG_NOTICE, 0, "opening library handle");
    *h = nfq_open();
    if (!(*h)) {
        tc_log_info(LOG_ERR, errno, "error during nfq_open()");
        return TC_INVALID_SOCK;
    }

    tc_log_info(LOG_NOTICE, 0,
            "unbinding existing nf_queue handler for AF_INET (if any)");
    if (nfq_unbind_pf((*h), AF_INET) < 0) {
        tc_log_info(LOG_ERR, errno, "error during nfq_unbind_pf()");
        return TC_INVALID_SOCK;
    }

    tc_log_info(LOG_NOTICE, 0,
            "binding nfnetlink_queue as nf_queue handler for AF_INET");
    if (nfq_bind_pf((*h), AF_INET) < 0) {
        tc_log_info(LOG_ERR, errno, "error during nfq_bind_pf()");
        return TC_INVALID_SOCK;
    }

    tc_log_info(LOG_NOTICE, 0, "binding this socket to queue");
    *qh = nfq_create_queue((*h),  0, cb, NULL);
    if (!(*qh)) {
        tc_log_info(LOG_ERR, errno, "error during nfq_create_queue()");
        return TC_INVALID_SOCK;
    }

    tc_log_info(LOG_NOTICE, 0, "setting copy_packet mode");
    if (nfq_set_mode((*qh), NFQNL_COPY_PACKET, REP_MAX_USEFUL_SIZE) < 0) {
        tc_log_info(LOG_ERR, errno, "can't set packet_copy mode");
        return TC_INVALID_SOCK;
    }

    if (max_queue_len > 0) {
        if (nfq_set_queue_maxlen((*qh), (uint32_t) max_queue_len)  < 0) {
            tc_log_info(LOG_ERR, errno, "can't set queue max length:%d", 
                    max_queue_len);
            tc_log_info(LOG_WARN, 0, "unable to set queue maxlen");
            tc_log_info(LOG_WARN, 0, "your kernel probably doesn't support it");
        }
    }

    fd = nfq_fd(*h);

    nfnl_rcvbufsiz(nfq_nfnlh(*h), 16777216);

    return fd;
}