Esempio n. 1
0
int
tc_nl_socket_init()
{
    int                  fd, rcvbuf;
    unsigned char        buf[128];
    struct nlmsghdr     *nl_header;
    struct sockaddr_nl   addr;
    struct ipq_mode_msg *mode_data;

   
    rcvbuf = 1048576;
   
    fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_FIREWALL);

    if (fd == -1) {
        tc_log_info(LOG_ERR, errno, "Create netlink socket failed");
        return TC_INVALID_SOCKET;
    }

    if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf)) == -1) {
        tc_log_info(LOG_ERR, errno,
                    "Set netlink socket(%d) recvbuf to (%d) failed",
                    fd, rcvbuf);
        return TC_INVALID_SOCKET;
    }
    tc_socket_set_nonblocking(fd);

    tc_memzero(&addr, sizeof(addr));
    tc_memzero(&buf, 128);

    addr.nl_family = AF_NETLINK;

    nl_header = (struct nlmsghdr *) buf;

    /* It must be ipq_peer_msg, not ipq_mode_msg */
    nl_header->nlmsg_len = NLMSG_LENGTH(sizeof(struct ipq_peer_msg));
    nl_header->nlmsg_flags = NLM_F_REQUEST;
    nl_header->nlmsg_type = IPQM_MODE;
    nl_header->nlmsg_pid = getpid();

    mode_data = NLMSG_DATA(nl_header);
    mode_data->value = IPQ_COPY_PACKET;
    mode_data->range = 65536;

    if (sendto(fd, (void *) nl_header, nl_header->nlmsg_len, 0,
               (struct sockaddr *) &addr, sizeof(struct sockaddr_nl)) == -1)
    {
        tc_log_info(LOG_ERR, errno,
                    "Set netlink socket(%d) mode failed, "
                    "check if ip queue is run", fd);
        return TC_INVALID_SOCKET;
    }

    return fd;
}
Esempio n. 2
0
/*
 * retrieve target addresses
 * format
 * 192.168.0.1:80-192.168.0.2:8080,192.168.0.1:8080-192.168.0.3:80
 */
static int
retr_target_addrs(char *raw_tf, transfer_maps_t *tf)
{
    int   i;
    char *p, *seq;

    if (raw_tf == NULL) {
        tc_log_info(LOG_ERR, 0, "it must have -x argument");
        fprintf(stderr, "no -x argument\n");
        return -1;
    }

    for (tf->num = 1, p = raw_tf; *p; p++) {
        if (*p == ',') {
            tf->num++;
        }
    }

    tf->map = tc_palloc(clt_settings.pool, tf->num * sizeof(transfer_map_t *));
    if (tf->map == NULL) {
        return -1;
    }
    tc_memzero(tf->map, tf->num * sizeof(transfer_map_t *));

    for (i = 0; i < tf->num; i++) {
        tf->map[i] = tc_palloc(clt_settings.pool, sizeof(transfer_map_t));
        if (tf->map[i] == NULL) {
            return -1;
        }
        tc_memzero(tf->map[i], sizeof(transfer_map_t));
    }

    p = raw_tf;
    i = 0;
    for ( ;; ) {
        if ((seq = strchr(p, ',')) == NULL) {
            if (parse_target(tf->map[i++], p) == -1) {
                return -1;
            }
            break;
        } else {
            *seq = '\0';
            if (parse_target(tf->map[i++], p) == -1) {
                return -1;
            }

            *seq = ',';
            p = seq + 1;
        }
    }

    return 0;
}
Esempio n. 3
0
int
tc_socket_listen(int fd, const char *bind_ip, uint16_t port)
{
    socklen_t          len; 
    struct sockaddr_in local_addr;

    tc_memzero(&local_addr, sizeof(local_addr));

    local_addr.sin_port   = ntohs(port);
    local_addr.sin_family = AF_INET;

    if (bind_ip) {
        /* set bind ip for security reasons */
        inet_aton(bind_ip, &local_addr.sin_addr);
    }

    len = (socklen_t) sizeof(local_addr);

    if (bind(fd, (struct sockaddr *) &local_addr, len) == -1) {
        tc_log_info(LOG_ERR, errno, "Bind socket(%d) to port:%d failed",
                    fd, port);
        return TC_ERROR;
    }

    if (listen(fd, 5) == -1) {
        tc_log_info(LOG_ERR, errno, "Listen socket(%d) failed", fd);
        return TC_ERROR;
    }

    return TC_OK;
}
Esempio n. 4
0
int
tc_socket_connect(int fd, uint32_t ip, uint16_t port)
{
    socklen_t           len;
    struct sockaddr_in  remote_addr;                           

    tc_memzero(&remote_addr, sizeof(remote_addr));               

    remote_addr.sin_family = AF_INET;                         
    remote_addr.sin_addr.s_addr = ip;                
    remote_addr.sin_port = htons(port);                       

    len = (socklen_t) (sizeof(remote_addr));

    if (connect(fd, (struct sockaddr *) &remote_addr, len) == -1) {
        tc_log_info(LOG_ERR, errno, "Can not connect to remote server(%s:%d)",
                inet_ntoa(remote_addr.sin_addr), port);
        tc_socket_close(fd);
        return TC_ERROR;
    } else {
        tc_log_info(LOG_INFO, 0, "connect to remote server(%s:%d)",
                inet_ntoa(remote_addr.sin_addr), port);
        return TC_OK;
    }

}
Esempio n. 5
0
/* retrieve ip addresses */
static int
retrieve_ip_addr()
{
    int          count = 0;
    char         tmp[32];
    size_t       len;
    uint32_t     address;
    const char  *split, *p;

    tc_memzero(tmp, 32);
    p = srv_settings.raw_ip_list;

    while (true) {
        split = strchr(p, ',');
        if (split != NULL) {
            len = (size_t) (split - p);
        } else {
            len = strlen(p);
        }

        strncpy(tmp, p, len);
        address = inet_addr(tmp);
        srv_settings.passed_ips.ips[count++] = address;

        if (count == MAX_ALLOWED_IP_NUM) {
            tc_log_info(LOG_WARN, 0, "reach the limit for passing firewall");
            break;
        }

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

        tc_memzero(tmp, 32);
    }

    srv_settings.passed_ips.num = count;

    return 1;
}
Esempio n. 6
0
static bool send_version(int fd) {
    msg_clt_t    msg;

    tc_memzero(&msg, sizeof(msg_clt_t));
    msg.type = htons(INTERNAL_VERSION);

    if (tc_socket_snd(fd, (char *) &msg, MSG_CLT_SIZE) == TC_ERR) {
        tc_log_info(LOG_ERR, 0, "send version error:%d", fd);
        return false;
    }

    return true;
}
Esempio n. 7
0
static int
read_conf_file()
{
#if (TC_PLUGIN)
    tc_buf_t         b;
    tc_conf_file_t   conf_file;

    tc_memzero(&conf_file, sizeof(tc_conf_file_t));
    tc_memzero(&b, sizeof(tc_buf_t));

    clt_settings.cf = tc_palloc(clt_settings.pool, sizeof(tc_conf_t));

    conf_file.file.fd = -1;
    conf_file.line = 0;

    clt_settings.cf->conf_file = &conf_file;
    clt_settings.cf->pool = clt_settings.pool;

    clt_settings.cf->args = tc_array_create(clt_settings.pool, 10,
            sizeof(tc_str_t));

    if (clt_settings.conf_file == NULL) {
        clt_settings.conf_file = TC_CONF_PATH;
    }

    clt_settings.conf_file = tc_conf_full_name(clt_settings.pool, TC_PREFIX,
            clt_settings.conf_file);

    if (tc_conf_parse(clt_settings.plugin, clt_settings.pool, clt_settings.cf,
            clt_settings.conf_file) != TC_OK) {
        return TC_ERR;
    }

    clt_settings.cf->conf_file = NULL;
#endif

    return TC_OK;
}
Esempio n. 8
0
int
tc_raw_socket_snd(int fd, void *buf, size_t len, uint32_t ip)
{
    ssize_t             send_len, offset = 0, num_bytes;
    const char         *ptr;
    struct sockaddr_in  dst_addr;

    if (fd > 0) {
        
        tc_memzero(&dst_addr, sizeof(struct sockaddr_in));

        dst_addr.sin_family = AF_INET;
        dst_addr.sin_addr.s_addr = ip;

        ptr = buf;

        /*
         * The output packet will take a special path of IP layer
         * (raw_sendmsg->raw_send_hdrinc->NF_INET_LOCAL_OUT->...).
         * No IP fragmentation will take place if needed. 
         * This means that a raw packet larger than the MTU of the 
         * interface will probably be discarded. Instead ip_local_error(), 
         * which does general sk_buff cleaning, is called and an 
         * error EMSGSIZE is returned. 
         */
        do {
            num_bytes = len - offset;
            send_len = sendto(fd, ptr + offset, num_bytes, 0, 
                    (struct sockaddr *) &dst_addr, sizeof(dst_addr));

            if (send_len >= 0) {
                offset += send_len;
            } else {

                if (errno == EINTR) {
                    tc_log_info(LOG_NOTICE, errno, "raw fd:%d EINTR", fd);
                } else if (errno == EAGAIN) {
                    tc_log_info(LOG_NOTICE, errno, "raw fd:%d EAGAIN", fd);
                } else {
                    tc_log_info(LOG_ERR, errno, "raw fd:%d", fd);
                    tc_socket_close(fd);
                    return TC_ERR;
                }
            }

        } while (offset < (ssize_t) len);
    } 

    return TC_OK;
}
static int 
proc_when_sess_created(tc_sess_t *s)
{
    tc_mysql_session *data = s->data;

    if (data == NULL) {
        data = (tc_mysql_session *) tc_pcalloc(s->pool, 
                sizeof(tc_mysql_session));

        if (data) {
            s->data = data;
        }

    } else {
        tc_memzero(data, sizeof(tc_mysql_session));
    }

    return TC_OK;
}
Esempio n. 10
0
int
tc_socket_listen(int fd, const char *bind_ip, uint16_t port)
{
    int                opt, ret;
    socklen_t          len; 
    struct sockaddr_in local_addr;

    tc_memzero(&local_addr, sizeof(local_addr));

    local_addr.sin_port   = ntohs(port);
    local_addr.sin_family = AF_INET;

    if (bind_ip) {
        /* set bind ip for security reasons */
        inet_aton(bind_ip, &local_addr.sin_addr);
    }

    opt = 1;
    ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
    if (ret == -1) {
        tc_log_info(LOG_ERR, errno, "setsockopt error");
        return TC_INVALID_SOCK;
    }

    len = (socklen_t) sizeof(local_addr);

    if (bind(fd, (struct sockaddr *) &local_addr, len) == -1) {
        tc_log_info(LOG_ERR, errno, "Bind socket(%d) to port:%u failed",
                    fd, port);
        fprintf(stderr, "Bind socket(%d) to port:%u failed\n", fd, port);
        return TC_ERR;
    }

    if (listen(fd, 5) == -1) {
        tc_log_info(LOG_ERR, errno, "Listen socket(%d) failed", fd);
        fprintf(stderr, "Listen socket(%d) failed\n", fd);
        return TC_ERR;
    }

    return TC_OK;
}
Esempio n. 11
0
int
set_signal_handler(signal_t *signals)
{
    int              status;
    signal_t        *sig;
    struct sigaction sa;

    for (sig = signals; sig->signo != 0; sig++) {
        tc_memzero(&sa, sizeof(sa));
        sa.sa_handler = sig->handler;
        sa.sa_flags = sig->flags;
        sigemptyset(&sa.sa_mask);

        status = sigaction(sig->signo, &sa, NULL);
        if (status < 0) {
            tc_log_info(LOG_ERR, errno, "sigaction(%s) failed", sig->signame);
            return -1;
        }
    }

    return 0;
}