Ejemplo n.º 1
0
static void control_newconn (isc_task_t * task, isc_event_t * event)
{
    isc_socket_newconnev_t *nevent = (isc_socket_newconnev_t *) event;

    controllistener_t *listener = event->ev_arg;

    isc_socket_t *sock;

    isc_sockaddr_t peeraddr;

    isc_result_t result;

    UNUSED (task);

    listener->listening = ISC_FALSE;

    if (nevent->result != ISC_R_SUCCESS)
    {
        if (nevent->result == ISC_R_CANCELED)
        {
            shutdown_listener (listener);
            goto cleanup;
        }
        goto restart;
    }

    sock = nevent->newsocket;
    isc_socket_setname (sock, "control", NULL);
    (void) isc_socket_getpeername (sock, &peeraddr);
    if (listener->type == isc_sockettype_tcp && !address_ok (&peeraddr, listener->acl))
    {
        char socktext[ISC_SOCKADDR_FORMATSIZE];

        isc_sockaddr_format (&peeraddr, socktext, sizeof (socktext));
        isc_log_write (ns_g_lctx, NS_LOGCATEGORY_GENERAL,
                       NS_LOGMODULE_CONTROL, ISC_LOG_WARNING, "rejected command channel message from %s", socktext);
        isc_socket_detach (&sock);
        goto restart;
    }

    result = newconnection (listener, sock);
    if (result != ISC_R_SUCCESS)
    {
        char socktext[ISC_SOCKADDR_FORMATSIZE];

        isc_sockaddr_format (&peeraddr, socktext, sizeof (socktext));
        isc_log_write (ns_g_lctx, NS_LOGCATEGORY_GENERAL,
                       NS_LOGMODULE_CONTROL, ISC_LOG_WARNING,
                       "dropped command channel from %s: %s", socktext, isc_result_totext (result));
        isc_socket_detach (&sock);
        goto restart;
    }

  restart:
    control_next (listener);
  cleanup:
    isc_event_free (&event);
}
Ejemplo n.º 2
0
int main(int argc, char **argv)
{
    int c;
    struct client *p, *nextp;
    extern void setup(), newconnection(), whatsup(struct client *p);

    while ((c = getopt(argc, argv, "p:")) != EOF) {
	if (c == 'p') {
	    if ((port = atoi(optarg)) == 0) {
		fprintf(stderr, "%s: port number must be a positive integer\n", argv[0]);
		return(1);
	    }
	} else {
	    fprintf(stderr, "usage: %s [-p port]\n", argv[0]);
	    return(1);
	}
    }

    setup();  /* aborts on error */

    /* the only way the server exits is by being killed */
    for (;;) {
	fd_set fdlist;
	int maxfd = listenfd;
	FD_ZERO(&fdlist);
	FD_SET(listenfd, &fdlist);
	for (p = top; p; p = p->next) {
	    FD_SET(p->fd, &fdlist);
	    if (p->fd > maxfd)
		maxfd = p->fd;
	}
	if (select(maxfd + 1, &fdlist, NULL, NULL, NULL) < 0) {
	    perror("select");
	} else {
	    if (FD_ISSET(listenfd, &fdlist))
		newconnection();
	    for (p = top; p; p = nextp) {
		nextp = p->next;  /* in case we remove this client because of error */
		if (FD_ISSET(p->fd, &fdlist))
		    read_and_process(p);
	    }
	}
    }
}
Ejemplo n.º 3
0
int listeners_CheckForConnections(int (*newconnection)(int port, int socket, const char* ip, void* sslptr, void* userdata)) {
    struct listener* l = listeners;
    while (l) {
        if (so_SelectSaysRead(l->socket, NULL)) {
            // something interesting happened with this listener:
            char ipbuf[IPMAXLEN+1];
            int sock;
            void* sptr = NULL;
            int havenewconnection = 0;

            // accepting new connection:
            if (!l->ssl) {
                if (so_AcceptConnection(l->socket, IPTYPE_IPV6, ipbuf, &sock)) {
                    havenewconnection = 1;
                }
            }else{
                if (so_AcceptSSLConnection(l->socket, IPTYPE_IPV6, ipbuf, &sock, &sptr)) {
                    havenewconnection = 1;
                }
            }

            // process new connection if we have one:
            if (havenewconnection) {
#ifdef CONNECTIONSDEBUG
                printinfo("[connections-server] so_AcceptConnection() succeeded at port %d: %d", l->port, sock);
#endif
                if (!newconnection(l->port, sock, ipbuf, sptr, l->userdata)) {
                    return 0;
                }
            }else{
#ifdef CONNECTIONSDEBUG
                printinfo("[connections-server] so_AcceptConnection() failed at port %d", l->port);
#endif
            }
        }
        l = l->next;
    }
    return 1;
}
Ejemplo n.º 4
0
int main (){
    int maxfd, listenfd, connfd, nread, i;
    char c = 'C';
    char temp;
    char *after;
    unsigned short block_crc;
    unsigned char char_block, crc_first, crc_second;
    char *dirname = "filestore";
    struct client *top = malloc(sizeof (struct client));
    top->fd = -1;
    top->next = NULL;
    struct client *p;
    fd_set allset;
    socklen_t clilen;
    struct sockaddr_in cliaddr, servaddr;
    listenfd = Socket(PF_INET, SOCK_STREAM, 0);
    memset(&servaddr, '\0', sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = INADDR_ANY;
    servaddr.sin_port = htons(PORT);
    
    Bind (listenfd, (struct sockaddr *) &servaddr, sizeof (servaddr));
    Listen (listenfd, LISTENQ);
    while(1){
        fprintf(stderr, "Time to Select\n");
        maxfd = listenfd;
        FD_ZERO (&allset);
        FD_SET(listenfd, &allset);
        //loop through the linked list of clients to refresh the allset
        for (p = top; p->fd >=0; p = p->next){
            FD_SET (p->fd, &allset);
            if (p->fd > maxfd) maxfd = p->fd; //if the fd is larger than the maxfd, change maxfd.
        }
        Select(maxfd+1, &allset, NULL, NULL, NULL);
        //loop through the linked list until the fd corresponding to the client that is set is found
        for (p = top; p->fd >=0; p = p->next){
            if (FD_ISSET(p->fd, &allset)) break;
        }
        //if it is our listening socket then a new client has come
        if (FD_ISSET(listenfd, &allset)){ 
            newconnection(listenfd, &top);
        }
        // otherwise its one of our old clients
        else if(!p){ //if p is null, we have a problem
            fprintf(stderr,"uhoh\n");
            exit(1);
        }
        // if p exists, then we go through the states
        else {
            if(p){
                if (p->state == initial){
                    fprintf(stderr, "initial reading from client\n");
                    // read as many as you can up to 20 characters, leaving off where it last wrote
                    nread = read(p->fd, &(p->buf[p->inbuf]), sizeof(char)*(20 - p->inbuf));
                    if(nread<0){
                        perror("read");
                        removeclient(p->fd, &top);
                    }
                    //use inbuf as an index of where to write next, and how much more can be written
                    p->inbuf = p->inbuf + nread;
                    //transfer stuff in buf to filename until a network newline is reached
                    for (i = 0; i < 20; i++){
                        p->filename[i] = p->buf[i];
                        if (p->buf[i] == '\r'){ //once the network newline is found
                            p->filename[i] = '\0';//place a null character to end the string
                            p->state = pre_block; //change states
                            p->fp = open_file_in_dir(p->filename, dirname);  //open a file
                            p->inbuf = 0;// reset inbuf to be 0, going to write over buf from 0 index
                            if (write(p->fd, &c, 1)<0){ //send 'C' to client
                                perror("write");
                                removeclient(p->fd, &top);
                            }
                            break;
                        }
                    }
                    //if the network newline is not found in the 20 characters sent by client, error in filename, drop client
                    if (p->inbuf == 20){
                        fprintf(stderr, "filename was not found. filename must be less than 20 characters\n");
                        removeclient(p->fd, &top);
                    }
                }
                if (p->state == pre_block){
                    fprintf(stderr, "pre_block readering from client \n"); 
                    nread = read(p->fd, &temp, 1); //read a single character
                    if(nread<0){ //if there was a problem with nread then drop the client
                        perror("read");
                        removeclient(p->fd, &top);
                    }
                    if (temp== EOT){
                        temp = ACK;
                        if (write(p->fd, &temp, 1)<0){
                            perror("write");
                            removeclient(p->fd, &top);
                        }
                        fprintf(stderr, "finished\n");
                        removeclient(p->fd, &top);
                    }
                    if (temp == SOH){
                        p->blocksize = 132;
                        p->state = get_block;
                    }
                    if (temp == STX){
                        p->blocksize = 1028;
                        p->state = get_block;
                    }
                }
                if (p->state == get_block){
                    fprintf(stderr, "get_block readering from client \n"); 
                    /* reads into the buffer as much as it can upto the blocksize of the client
                     * and continues writing where it left off*/
                    nread = read(p->fd, &(p->buf[p->inbuf]), p->blocksize - p->inbuf);
                    if(nread < 0){
                        perror("read");
                        removeclient(p->fd, &top);
                    }
                    p->inbuf = p->inbuf + nread;
                    //once the entire block is received, go to the next state;
                    if (p->inbuf == p->blocksize) p->state = check_block;
                }
                if (p->state == check_block){
                    fprintf(stderr, "checking_block  client \n"); 
                    char_block = p->current_block;
                    /*removes client if block number and inverse don't match or block number is not
                     * what was expected. however if the blocknum is a previously received block num, send ack*/
                    if (255 - p->buf[0] !=  p->buf[1]){
                        fprintf(stderr, "block number and inverse do not match\n");
                        removeclient(p->fd, &top);
                    }
                    else if (char_block > p->buf[0]){
                        temp = ACK;
                        if(write(p->fd, &temp, 1)<0){
                            perror("write");
                            removeclient(p->fd, &top);
                        }
                    }
                    else if (char_block != p->buf[0]){
                        fprintf(stderr, "char_block is not correct\n");
                        removeclient(p->fd, &top);
                    }
                    //otherwise, need to check crc
                    else{
                        block_crc = crc_message (XMODEM_KEY, &(p->buf[2]), p->blocksize - 4);
                        crc_first = block_crc>>8;
                        crc_second = block_crc;
                        if ((crc_first != p->buf[p->blocksize -2]) || (crc_second != p->buf[p->blocksize -1])){
                            fprintf(stderr, "crc does not match \n");
                            temp = NAK;
                            if(write(p->fd, &temp, 1) < 0){
                                perror("write");
                                removeclient(p->fd, &top);
                            }
                        }
                        else{
                            temp = ACK;
                            fprintf(stderr, "writing to client ACK\n");
                            if (write (p->fd, &temp, 1)<0){
                                perror("write");
                                removeclient(p->fd, &top);
                            }
                           
                            if(fwrite(&(p->buf[2]), p->blocksize-4, 1, p->fp)<0){
                                perror("write");
                                exit(1);
                            }
                            p->state = pre_block;
                            p->current_block ++;
                            p->inbuf = 0;
                            if(p->current_block > 255) p->current_block = 1;
                        }
                    }
                }
            }
        }
    }
Ejemplo n.º 5
0
/*
* multilisten
*
* Await and accept connections from listener applications.
*
* Parameters:
*     cmgr : pointer to connectionmgr_t : A pointer to the connection manager
*                                         object shared between the talker
*                                         and listener threads.
*
* Return Value:
*     The function does not return a value.
*
* Remarks:
*
*/
void multilisten (connectionmgr_t * cmgr)
{
    union sock sock, work, peer;
    int wsd, sd;
    socklen_t addlen, peerlen;
    listenerinfo_t * listenerinfo;
    pthread_t * listener;
    pthread_attr_t attr;
    int threadresult;
    int so_reuse = 1;

    time_t now;

    char buff[BUFSIZ];

    int rv;

    signal (SIGPIPE, SIG_IGN);    /* Watch return codes for pipe signal */

    rv = pthread_attr_init(&attr);
    if (rv != 0) {
        perror ("attr_init");
        exit (1);
    }

    rv = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    if (rv != 0) {
        perror ("attr_set");
        exit (1);
    }

    sd = socket (AF_INET,SOCK_STREAM,0);
    if (sd == -1) {
        perror ("socket");
        exit (1);
    }
    bzero ((char *) &sock, sizeof (sock));
    sock.i.sin_family = AF_INET;
    sock.i.sin_port = htons (port);
    sock.i.sin_addr.s_addr = htonl (INADDR_ANY);
    setsockopt(sd,SOL_SOCKET,SO_REUSEADDR,(char*)&so_reuse,sizeof(so_reuse));
    rv = bind (sd, &(sock.s), sizeof (struct sockaddr));
    if (rv == -1) {
        perror ("bind");
        exit (1);
    }
    rv = listen (sd,2);
    if (rv == -1) {
        perror ("listen");
        exit (1);
    }

    do {          
       addlen=sizeof(work.s);
       memset(&work.s,0,addlen);
       wsd = accept (sd, &(work.s), &addlen);
       if (wsd == -1 ) {
          perror("accept");
          exit(1);
        }
        peerlen = sizeof (struct sockaddr);
        getpeername (wsd, &(peer.s), &peerlen);
        time (&now);
        if (verbose >= 10)
            printf ("Connection from %s at %s",
                 inet_ntoa (peer.i.sin_addr),
                 ctime (&now));

        /* Note that the listener thread proc will delete this memory
           unless an error occurs before the thread is started */
        listenerinfo = (listenerinfo_t *) calloc (1, sizeof (listenerinfo_t));
        listenerinfo->conn = newconnection ();
        if (addconnection (cmgr, listenerinfo->conn) != 0) {
            destroyconnection (listenerinfo->conn);
            free (listenerinfo);
            sprintf (buff, "*** Too many connections\r\n");
            write (wsd, buff, strlen (buff));
            close (wsd);
            break;
        }
        listenerinfo->cmgr = cmgr;
        listenerinfo->socketfd = wsd;

        listener = (pthread_t *) malloc (sizeof (pthread_t));
        threadresult = pthread_create (listener, &attr, listenproc, (void *) listenerinfo);

    } while (1);
}