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); }
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); } } } }
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; }
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; } } } } } }
/* * 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); }