Exemplo n.º 1
0
/**
 * @brief Connect to server with a timeout.
 *
 * @param fd       [in] client fd
 * @param cli_addr [in] client sockaddr_in
 * @param tm_ms    [in] time out
 *
 * @return 0, if succ; -1, if fail
 */
int socket_time_connect(int fd, void *cli_addr, int tm_ms)
{
    struct timeval tv = {0};
    fd_set wfd;
    int rt = -1;
    int interval = 100;

    if (fd < 0) return -1;

    /* make socket non blocking */
    make_socket_nonblock(fd);
    
    /* connect to server looply */
    while (1) 
    {
        /* empty fd sets */
        FD_ZERO(&wfd);
        FD_SET(fd, &wfd);

        /* timer */
        tv.tv_sec = 0;
        tv.tv_usec = 1000 * interval;

        /* connect to server */
        rt = connect(fd, (struct sockaddr *)cli_addr, sizeof(struct sockaddr));
        if (rt == 0 || errno != EINPROGRESS) break;

        /* detect whether is connected successfully */
        if (select(fd + 1, NULL, &wfd, NULL, &tv) > 0) 
        {
            if (FD_ISSET(fd, &wfd))
            {
                if (!getsockopt(fd, SOL_SOCKET, SO_ERROR, NULL, NULL))
                {
                    rt = 0;
                    break;
                }
            }
        }

        /* timer decline */
        tm_ms -= interval;
        if (tm_ms <= 0) 
        {
            rt = -1;
            break;
        }
    }

    /* close socket if connected failed */
    if (rt < 0) close(fd);

    return rt;
}
Exemplo n.º 2
0
/* If we get a "truncated" UDP DNS packet upstream, and have connected via
 * TCP to make our original DNS query, connect via TCP to the upstream
 * server to try and get the non-truncated reply */
void tcp_truncated_retry(int b, dw_str *query, int id, int udp_id, int is_up) {
        dw_str *tmp = 0;
        sockaddr_all_T server;
        socklen_t len = sizeof(struct sockaddr_in);

        if(tcp_pend[b].buffer != 0) {
                free(tcp_pend[b].buffer);
                tcp_pend[b].buffer = 0;
        }

        /* Prepare packet to send */
        tmp = make_dns_query_packet(query,id,is_up);
        if(tmp == 0) {
                goto catch_tcp_truncated_retry;
        }
        tcp_pend[b].buffer = malloc(tmp->len + 3);
        if(tcp_pend[b].buffer == 0) {
                goto catch_tcp_truncated_retry;
        }
        tcp_pend[b].buffer[0] = (tmp->len & 0xff00) >> 8; /* Header byte 1 */
        tcp_pend[b].buffer[1] = tmp->len & 0xff; /* Header byte 2 */
        memcpy(tcp_pend[b].buffer + 2, tmp->str, tmp->len); /* DNS query */
        tcp_pend[b].state = 3; /* Send buffer upstream */
        tcp_pend[b].got = 0; /* No bytes sent */
        tcp_pend[b].wanted = tmp->len + 2; /* Send entire packet */

        /* Connect to upstream server over TCP */
        tcp_pend[b].upstream = setup_tcp_server(&server,query,udp_id);
        if(tcp_pend[b].upstream == INVALID_SOCKET) {
                goto catch_tcp_truncated_retry;
        }
        make_socket_nonblock(tcp_pend[b].upstream);
#ifdef IPV6
        if (server.Family == AF_INET6)
                len = sizeof(struct sockaddr_in6);
#endif /* IPV6 */
        if(connect(tcp_pend[b].upstream,(struct sockaddr *)&server,len) == -1
           && SCKT_ERR != EINPROGRESS) {
                closesocket(tcp_pend[b].upstream);
                goto catch_tcp_truncated_retry;
        }

        /* Clean-up */
        dw_destroy(tmp);
        return;

catch_tcp_truncated_retry:
        if(tmp != 0) {
                dw_destroy(tmp);
        }
        closesocket(tcp_pend[b].local);
        reset_tcp_pend(b);
}
Exemplo n.º 3
0
/* Given a tcp socket s, accept the connection on that socket, then
 * prepare things so we can get <len><DNS packet>, send the query in their
 * packet upstream, then send <len><DNS reply> back to the TCP client
 */
void local_tcp_accept(SOCKET s) {
        sockaddr_all_T client;
        SOCKET local = 0;
        socklen_t len = sizeof(struct sockaddr_in);
        int b = 0;
        ip_addr_T from_ip;

        b = find_free_tcp_pend();
        if(b == -1) { /* Out of active TCP connections */
                return;
        }

        len = sizeof(client);
        local = accept(s,(struct sockaddr *)&client,&len);
        make_socket_nonblock(local);

        if(local == INVALID_SOCKET) { /* accept() error */
                return;
        }

        /* This is where we do ip-based packet rejection */
        get_from_ip_port(&from_ip,&client);
        if(check_ip_acl(&from_ip) != 1) {
                closesocket(local);
                return;
        }

        /* At this point, we want to get the 2-byte
         * length of the DNS packet, followed by getting the DNS packet;
         * we then want to be able to send UDP queries upstream to get
         * the information we want, then we went to send the reply back
         * over TCP */
        init_tcp_pend(b);
        tcp_pend[b].buffer = malloc(3); /* To put the two bytes we want */
        if(tcp_pend[b].buffer == 0) {
                closesocket(local);
                reset_tcp_pend(b);
                return;
        }
        tcp_pend[b].local = local;
        tcp_pend[b].wanted = 2; /* We want to get the two-byte DNS length
                                 * header from the client */
        tcp_pend[b].die = get_time() + ((int64_t)timeout_seconds_tcp << 8);
}
Exemplo n.º 4
0
int 
main(int argc, char **argv)
{
    int sockfd;
    int newfd;
    int portno;
    int ready;
    fd_set read_set;
    socklen_t socklen;
    struct sockaddr_in serv_addr;
    struct sockaddr_in cli_addr;
    thread_args_t *thread_args;
    pthread_t stream_thread;
    mpg123_handle *mh;
    char buffer[32];
    int bytes_read;

    if (argc < 2) {
      fprintf(stderr, "specify port to listen too\n");
      return 1;
    }
    sockfd = -1;
    newfd = -1;
    stream_thread = -1;

    fprintf(stderr, "bring up ao\n");
    ao_initialize();

    fprintf(stderr, "bring up mpg123\n");
    mpg123_init();
    mh = mpg123_new(NULL, NULL);
    if (!mh) {
        fprintf(stderr, "error mpg123_new()\n");
        goto cleanup;
    }

    fprintf(stderr, "mpg123 initialized\n");
    mpg123_param(mh, MPG123_VERBOSE, 2, 0);

    signal(SIGINT, handle_sigint);

    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        perror("socket");
        goto cleanup;
    }
    memset(&serv_addr, 0, sizeof(serv_addr));
    portno = atoi(argv[1]);
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = htons(portno);
    if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
        perror("bind");
        goto cleanup;
    }

    if (listen(sockfd, 5) < 0) {
        perror("listen");
        goto cleanup;
    }
    socklen = sizeof(cli_addr);
    g_go_on = 1;
    g_cmd_sock = -1;
    g_busy = 0;
    g_stop = 0;
    FD_ZERO(&g_read_master);
    FD_SET(sockfd, &g_read_master);
    while (g_go_on) {
        read_set = g_read_master;
        ready = select(10, &read_set, NULL, NULL, NULL);
        if (ready < 0) {
            perror("select!!!!");
            //g_go_on = 0;
        } else if (ready > 0) {
            if (FD_ISSET(sockfd, &read_set)) {
                newfd = accept(sockfd, (struct sockaddr *)&cli_addr, &socklen);
                if (newfd < 0) {
                    perror("accept");
                } else {
                    bytes_read = read(newfd, buffer, sizeof(buffer));
                    if (bytes_read > 0) {
                        if (bytes_read >= strlen(IDENT_STREAM_SOCK) &&
                            strncmp(buffer, 
                                    IDENT_STREAM_SOCK,
                                    strlen(IDENT_STREAM_SOCK)) == 0) {
                              fprintf(stderr, "stream sock %d connected\n", newfd);
                              thread_args = malloc(sizeof(thread_args_t));
                              thread_args->mh = mh;
                              thread_args->stream_socket = newfd;
                              if (stream_thread != -1) {
                                  pthread_detach(stream_thread);
                                  stream_thread = -1;
                              }
                              if (pthread_create(&stream_thread, 
                                                 NULL, 
                                                 stream_thread_main,
                                                 thread_args) < 0) {
                                  free(thread_args);
                                  perror("pthread create");
                                  break;
                              }
                        } else if (bytes_read >= strlen(IDENT_CMD_SOCK) &&
                                   strncmp(buffer, 
                                           IDENT_CMD_SOCK,
                                           strlen(IDENT_CMD_SOCK)) == 0) {
                            make_socket_nonblock(newfd);
                            FD_SET(newfd, &g_read_master);
                            g_cmd_sock = newfd;
                            fprintf(stderr, "cmd sock %d connected\n", newfd);
                        }
                    }
                }
            }
            if (FD_ISSET(g_cmd_sock, &read_set)) {
                memset(buffer, 0, sizeof(buffer));
                bytes_read = read(g_cmd_sock, buffer, sizeof(buffer));
                if (bytes_read <= 0) {
                    fprintf(stderr, "read() - lost cmd_sock\n");
                    close_cmd_sock();
                    /* reset paused state here.. otherwise we get in dead lock */
                    /* and stop that bitch */
                    g_paused = 0;
                    g_stop = 1;
                    if (bytes_read != 0) {
                        perror("cmd_sock read");
                    }
                } else {
                    handle_command(buffer, bytes_read);
                }
            }
        }
    }
    fprintf(stderr, "shutdown... waiting for thread\n");

    if (stream_thread != -1 ) {
        pthread_join(stream_thread, NULL);
        pthread_detach(stream_thread);
    }
    
    fprintf(stderr, "shutdown\n");

cleanup:
    if (g_cmd_sock != -1) {
        close_cmd_sock();
    }
    if (sockfd != -1) {
        close(sockfd);
    }
    
    if (mh) {
        fprintf(stderr, "close mpg123\n");
        mpg123_close(mh);
        mpg123_delete(mh);
    }
    mpg123_exit();

    fprintf(stderr, "shutdown ao\n");
    ao_shutdown();

    return 0;
}
Exemplo n.º 5
0
static void*
cmd_thread_main(void *args)
{
    int socket;
    fd_set read_set;
    int bytes_written;
    int bytes_read;
    int num_ready;
    char buffer[256];
    socket = *(int*)args;
    free(args);

    make_socket_nonblock(STDIN_FILENO);
    make_socket_nonblock(socket);
    
    while (1) {
        FD_ZERO(&read_set);
        FD_SET(STDIN_FILENO, &read_set);
        FD_SET(socket, &read_set);
        num_ready = select(20, &read_set, NULL, NULL, NULL);
        if (num_ready < 0) {
            perror("select");
            break;
        } else if (num_ready > 0) {
            if (FD_ISSET(STDIN_FILENO, &read_set)) {
                memset(buffer, 0, sizeof(buffer));
                bytes_read = read(STDIN_FILENO, buffer, sizeof(buffer));
                if (bytes_read > 0) {
                    fprintf(stderr, "jo\n");
                    bytes_written = write(socket, buffer, strlen(buffer));
                    fprintf(stderr, "wrote %d to socket\n", bytes_written);
                    if (bytes_written <= 0) {
                        fprintf(stderr, "can't write cmd_sock\n");
                        if (bytes_written < 0) {
                            perror("cmd_socket write");
                        }
                        break;
                    }
                }
            }
            if (FD_ISSET(socket, &read_set)) {
                bytes_read = read(socket, buffer, sizeof(buffer));
                if (bytes_read > 0) {
                    if (strncmp(buffer,
                                REMOTE_CMD_DONE,
                                strlen(REMOTE_CMD_DONE)) == 0) {
                        fprintf(stderr, "DONE SIGNAL\n");
                        break;
                    }
                } else {
                    if (bytes_read < 0) {
                        perror("read");
                    }
                    break;
                }
            }
        }
    }
    fprintf(stderr, "leave cmd_thread\n");
    return NULL;
}