void read_socket () { int count, flag, i ; char buf[80]; int gotcmd ; int cbufsiz ; int read_attempts ; gotcmd=0; cbufsiz = 0; incmdbuf[cbufsiz] = '\0' ; read_attempts = 0 ; while(gotcmd==0) { /* Set up non-blocking read from the socket */ flag = MSG_DONTWAIT ; i = 1 ; count = recv(sockpath, buf, i, flag); if (count > 0) { if (count+cbufsiz>80) { fprintf(stderr,"Buffer size exceeded - closing connection\n"); close_client_connection() ; break; } if (buf[0] < ' ') break ; memcpy(&incmdbuf[cbufsiz],buf,count); cbufsiz+= count; incmdbuf[cbufsiz] = '\0'; } else { /* Unable to read from the socket */ if (errno == EAGAIN) { /* Read would block - exit if byte(s) read from the socket, else declare timeout or sleep */ if (cbufsiz > 0) break ; ++read_attempts ; if (read_attempts == 100) { fprintf (stderr, "Read timed out - closing connection\n") ; close_client_connection() ; break ; } sleep(1) ; } else { fprintf(stderr,"Read error from client - closing connection\n"); close_client_connection() ; break; } } } }
void send_data (void *data) { int len; int i, flag, send_attempts ; int iSent; char *bufptr; /* Set up non-blocking write to the socket */ send_attempts = 0 ; iSent = 0; bufptr = data; len = strlen(data); while (send_attempts < 200 && iSent < len) { ++send_attempts; flag = MSG_DONTWAIT ; i = send(sockpath, &bufptr[iSent], len-iSent, flag); //fprintf (stderr, "DEBUG Bytes sent = %i\n", i) ; if (i < 0) { if (errno==EAGAIN) { fprintf(stderr, "DEBUG Would block error\n") ; if (send_attempts>=120) { fprintf(stderr,"Write timed out - closing connection") ; close_client_connection() ; return ; } sleep(1) ; } else { if ((errno==ENOTCONN) || (errno==EPIPE)) fprintf(stderr,"Client Disconnected\n"); else fprintf(stderr,"error on send (%x)\n", errno) ; close_client_connection() ; return ; } } // Error return from send else { iSent += i; if (iSent < len) sleep(1); } // send was good } // while send not timed out // Make sure record was sent if (iSent < len) { fprintf(stderr,"Write too many attempts- closing connection") ; close_client_connection() ; } } // send_data()
/** * Reads the thread specific userdata to figure out what * we need to handle. Things that purely effect the network * stack should be handled here, but otherwise we should defer * to the connection handlers. */ static void invoke_event_handler(ev_io *watcher, int ready_events) { // Get the user data worker_ev_userdata *data = ev_userdata(); // Read in the data, and close on issues conn_info *conn = watcher->data; if (read_client_data(conn)) { close_client_connection(conn); return; } // Invoke the connection handler, and close connection on error statsite_conn_handler handle = {data->netconf->config, watcher->data}; if (handle_client_connect(&handle)) close_client_connection(conn); }
/** * Shuts down all the connections * and listeners and prepares to exit. * @arg netconf The config for the networking stack. */ int shutdown_networking(statsite_networking *netconf) { // Stop listening for new connections if (ev_is_active(&netconf->tcp_client)) { ev_io_stop(&netconf->tcp_client); close(netconf->tcp_client.fd); } if (ev_is_active(&netconf->udp_client)) { ev_io_stop(&netconf->udp_client); close(netconf->udp_client.fd); } if (netconf->stdin_client != NULL) { close_client_connection(netconf->stdin_client); netconf->stdin_client = NULL; } // Stop the other timers ev_timer_stop(&netconf->flush_timer); // TODO: Close all the client connections // ??? For now, we just leak the memory // since we are shutdown down anyways... // Free the event loop ev_loop_destroy(EV_DEFAULT); // Free the netconf free(netconf); return 0; }
/** * Invoked when a client connection is ready to be written to. */ static void handle_client_writebuf(ev_loop *lp, ev_io *watcher, int ready_events) { // Get the associated connection struct conn_info *conn = watcher->data; // Build the IO vectors to perform the write struct iovec vectors[2]; int num_vectors; circbuf_setup_writev_iovec(&conn->output, (struct iovec*)&vectors, &num_vectors); // Issue the write ssize_t write_bytes = writev(watcher->fd, (struct iovec*)&vectors, num_vectors); if (write_bytes > 0) { // Update the cursor circbuf_advance_read(&conn->output, write_bytes); // Check if we should reset the use_write_buf. // This is done when the buffer size is 0. if (conn->output.read_cursor == conn->output.write_cursor) { conn->use_write_buf = 0; ev_io_stop(lp, &conn->write_client); } } // Handle any errors if (write_bytes <= 0 && (errno != EAGAIN && errno != EINTR)) { syslog(LOG_ERR, "Failed to write() to connection [%d]! %s.", conn->client.fd, strerror(errno)); close_client_connection(conn); return; } }
void reply_to_external_command(int result) { if (sClientConnection < 0) return; // prepare the reply external_command_reply reply; reply.error = result; // send the reply int toWrite = sizeof(reply); char *replyBuffer = (char*)&reply; ssize_t bytesWritten; do { bytesWritten = write(sClientConnection, replyBuffer, toWrite); if (bytesWritten > 0) { replyBuffer += bytesWritten; toWrite -= bytesWritten; } } while (toWrite > 0 && !(bytesWritten < 0 && errno != EINTR)); // connection may be broken: discard it if (bytesWritten < 0) close_client_connection(); }
void write_log_record() { /* Copy final (legacy) message to the log record */ send_data ("Finished\n") ; sleep(3); fprintf(stderr, "Done processing request\n"); if (client_connected == 1) close_client_connection() ; }
char * get_external_command(const char *prompt, char *input, int len) { do { // get a connection int connection = get_client_connection(); if (connection < 0) return NULL; // read until we have a full command external_command_message message; int toRead = sizeof(message); char *buffer = (char*)&message; while (toRead > 0) { int bytesRead = read(connection, buffer, toRead); if (bytesRead < 0) { if (errno == EINTR) { continue; } else { fprintf(stderr, "Reading from connection failed: %s\n", strerror(errno)); break; } } // connection closed? if (bytesRead == 0) break; buffer += bytesRead; toRead -= bytesRead; } // connection may be broken: discard it if (toRead > 0) { close_client_connection(); continue; } // get the len of the command message.command[sizeof(message.command) - 1] = '\0'; int commandLen = strlen(message.command) + 1; if (commandLen <= 1) { fprintf(stderr, "No command given.\n"); continue; } if (commandLen > len) { fprintf(stderr, "Command too long. Ignored.\n"); continue; } // copy the command memcpy(input, message.command, commandLen); input[len - 1] = '\0'; // always NULL-terminate return input; } while (true); }
void read_from_client(Maintainer* maintainer, int current_socket, Node* node) { logger("<Server><read_from_client>read from client\n"); int valread = read(current_socket, maintainer->buffer, BUFFER_SIZE); if(valread == 0){ close_client_connection(maintainer, current_socket, node); return; } process_command(maintainer, node); }
static int send_client_response_direct(conn_info *conn, char **response_buffers, int *buf_sizes, int num_bufs) { // Stack allocate the iovectors struct iovec *vectors = alloca(num_bufs * sizeof(struct iovec)); // Setup all the pointers ssize_t total_bytes = 0; for (int i=0; i < num_bufs; i++) { vectors[i].iov_base = response_buffers[i]; vectors[i].iov_len = buf_sizes[i]; total_bytes += buf_sizes[i]; } // Perform the write ssize_t sent = writev(conn->client.fd, vectors, num_bufs); if (sent == total_bytes) return 0; // Check for a fatal error if (sent == -1) { if (errno != EAGAIN && errno != EINTR && errno != EWOULDBLOCK) { syslog(LOG_ERR, "Failed to send() to connection [%d]! %s.", conn->client.fd, strerror(errno)); close_client_connection(conn); return 1; } } // Figure out which buffer we left off on int skip_bytes = 0; int index = 0; for (index; index < num_bufs; index++) { skip_bytes += buf_sizes[index]; if (skip_bytes > sent) { skip_bytes -= buf_sizes[index]; break; } } // Copy the buffers int res, offset; for (int i=index; i < num_bufs; i++) { offset = 0; if (i == index && skip_bytes < sent) { offset = sent - skip_bytes; } res = circbuf_write(&conn->output, response_buffers[i] + offset, buf_sizes[i] - offset); if (res) return 1; } // Setup the async write conn->use_write_buf = 1; ev_io_start(conn->thread_ev->loop, &conn->write_client); // Done return 0; }
/* * Invoked when client read data is ready. * We just read all the available data, * append it to the buffers, and then invoke the * connection handlers. */ static void invoke_event_handler(ev_loop *lp, ev_io *watcher, int ready_events) { // Get the user data worker_ev_userdata *data = ev_userdata(lp); // Read in the data, and close on issues conn_info *conn = watcher->data; if (read_client_data(conn)) { close_client_connection(conn); return; } // Prepare to invoke the handler bloom_conn_handler handle; handle.config = data->netconf->config; handle.mgr = data->netconf->mgr; handle.conn = conn; // Reschedule the watcher, unless it's non-active now if (handle_client_connect(&handle) || !conn->active) close_client_connection(conn); }
nvqrReturn_t nvqr_disconnect(NVQRConnection *connection) { if (disconnect_from_server(*connection)) { close_client_connection(*connection); destroy_client(*connection); close_server_connection(connection->server_handle); free(connection->process_name); return NVQR_SUCCESS; } return NVQR_ERROR_UNKNOWN; }
/** * Invoked when a client connection has data ready to be read. * We need to take care to add the data to our buffers, and then * invoke the connection handlers who have the business logic * of what to do. */ static int handle_client_data(ev_io *watch, worker_ev_userdata* data) { // Get the associated connection struct conn_info *conn = watch->data; /** * Figure out how much space we have to write. * If we have < 50% free, we resize the buffer using * a multiplier. */ int avail_buf = circbuf_avail_buf(&conn->input); if (avail_buf < conn->input.buf_size / 2) { circbuf_grow_buf(&conn->input); } // Build the IO vectors to perform the read struct iovec vectors[2]; int num_vectors; circbuf_setup_readv_iovec(&conn->input, (struct iovec*)&vectors, &num_vectors); // Issue the read ssize_t read_bytes = readv(watch->fd, (struct iovec*)&vectors, num_vectors); // Make sure we actually read something if (read_bytes == 0) { syslog(LOG_DEBUG, "Closed client connection. [%d]\n", conn->client.fd); close_client_connection(conn); return 1; } else if (read_bytes == -1) { if (errno != EAGAIN && errno != EINTR) { syslog(LOG_ERR, "Failed to read() from connection [%d]! %s.", conn->client.fd, strerror(errno)); close_client_connection(conn); } return 1; } // Update the write cursor circbuf_advance_write(&conn->input, read_bytes); return 0; }
int read_from_client(Maintainer* maintainer, int current_socket, Node* node) { logger("<Server><read_from_client>read from client\n"); int return_value = 0; int valread = read(current_socket, node->read_msg.buffer+node->read_msg.offset, BUFFER_SIZE-node->read_msg.offset); if(valread == 0) { close_client_connection(maintainer, current_socket, node, FALSE); return 1; } node->read_msg.offset += valread; if(node->read_msg.offset == node->read_msg.total_len) { logger("<Server><read_from_client>got a full message\n"); return_value = process_command(maintainer, node); node->read_msg.offset=0; } return return_value; }
//----------------------------------------------------------------------------- // Send NVQR_QUERY_CONNECT to the server and verify that it ACKs with // NVQR_QUERY_CONNECT. Returns TRUE on success; FALSE on failure. static bool connect_to_server(NVQRConnection *conn) { NVQRQueryDataBuffer data; bool ret = write_server_command(*conn, NVQR_QUERY_CONNECT, 0, get_my_pid()); if (ret) { ret = open_client_connection(conn); if (ret) { if (!read_server_response(*conn, &data) || data.op != NVQR_QUERY_CONNECT) { close_client_connection(*conn); } } } return ret; }
/** * Invoked when a client connection is ready to be written to. */ static int handle_client_writebuf(ev_io *watch, worker_ev_userdata* data) { // Get the associated connection struct conn_info *conn = watch->data; // Build the IO vectors to perform the write struct iovec vectors[2]; int num_vectors; circbuf_setup_writev_iovec(&conn->output, (struct iovec*)&vectors, &num_vectors); // Issue the write ssize_t write_bytes = writev(watch->fd, (struct iovec*)&vectors, num_vectors); int reschedule = 0; if (write_bytes > 0) { // Update the cursor circbuf_advance_read(&conn->output, write_bytes); // Check if we should reset the use_write_buf. // This is done when the buffer size is 0. if (conn->output.read_cursor == conn->output.write_cursor) { conn->use_write_buf = 0; } else { reschedule = 1; } } // Handle any errors if (write_bytes <= 0 && (errno != EAGAIN && errno != EINTR)) { syslog(LOG_ERR, "Failed to write() to connection [%d]! %s.", conn->client.fd, strerror(errno)); close_client_connection(conn); decref_client_connection(conn); return 1; } // Check if we should reschedule or end if (reschedule) { schedule_async(data->netconf, SCHEDULE_WATCHER, &conn->write_client); } else { decref_client_connection(conn); } return 0; }
static int send_proxy_msg_direct(conn_info *conn, char *msg_buffer, int buf_size) { // Stack allocate the iovectors struct iovec vector; // Setup all the pointers vector.iov_base = msg_buffer; vector.iov_len = buf_size; // Perform the write ssize_t sent = writev(conn->client.fd, &vector, 1); if (sent == buf_size) return 0; // Check for a fatal error if (sent == -1) { if (errno != EAGAIN && errno != EINTR && errno != EWOULDBLOCK) { syslog(LOG_ERR, "Failed to send() to connection [%d]! %s.", conn->client.fd, strerror(errno)); // Probably want to try and reopen connection here??? close_client_connection(conn); return 1; } } // Copy unsent data to circ buffer int res; if (sent < buf_size) { res = circbuf_write(&conn->output, msg_buffer + sent, buf_size - sent); if (res) { return 1; } } // Setup the async write conn->use_write_buf = 1; incref_client_connection(conn); schedule_async(conn->netconf, SCHEDULE_WATCHER, &conn->write_client); // Done return 0; }
void process_newclient(t_client *c, const t_trame *t, void *data) { printf("process new %d\n", (int)c);fflush(stdout); if (!t) {printf("very begininng\n");fflush(stdout);} else if (is_valid_trame((t_trame*)t, WELCOME)) { if (!nb_player) { players = (t_client**)malloc(sizeof(*players) * MAX_PLAYERS); for (int i = 0; i < MAX_PLAYERS; i++) players[i] = NULL; } if (nb_player >= MAX_PLAYERS) nb_player = 0; if (players[nb_player]) { printf("CLOSE ONE %d\n", (int)players[nb_player]); close_client_connection(players[nb_player]); printf("CLOSED %d\n", players[nb_player]->state);fflush(stdout); } // change status of client authorize_client(c); // collect information players[nb_player] = c; // for sending message later set_data_client(c, (void*)&players[nb_player]); // for receving msg nb_player++; printf("client %d say welcome\n", c);fflush(stdout); } else printf("ERROR: got %d\n", t->tag); }
int process_command(Maintainer* maintainer, Node* node) { char command = maintainer->buffer[0]; if(command == 'a'){ /*add file*/ logger("<Server><process_command>got add file command\n"); char tmp_name[FILENAME_MAX]; sscanf(maintainer->buffer, "a %s", tmp_name); int j = MAX_FILES; int i; for(i=0;i<MAX_FILES;++i) if(!strcmp(tmp_name,maintainer->files[i].name)) break; else if(maintainer->files[i].name[0] == '\0') j = i; if(i != MAX_FILES){ for(int k=0;k<MAX_CLIENTS; ++k) if(maintainer->files[i].owners[k] == node->socket_fd) return 0; else if(maintainer->files[i].owners[k] == -1) j=k; else continue; maintainer->files[i].owners[j] = node->socket_fd; maintainer->files[i].num_of_owners++; strcpy(maintainer->files[i].name, tmp_name); }else{ strcpy(maintainer->files[j].name, tmp_name); for(int i=0; i<MAX_CLIENTS; ++i) maintainer->files[j].owners[i] = -1; maintainer->files[j].num_of_owners=1; maintainer->files[j].owners[0] = node->socket_fd; } return 0; }else if(command == 'q'){ logger("<Server><process_command>got close connection command\n"); close_client_connection(maintainer, node->socket_fd, node); return 0; }else if(command == 'l'){ sscanf(maintainer->buffer, "l %d", &(node->listening_port)); logger("<Server><process_command>got listening port as %d\n", node->listening_port); return 0; }else if(command == 'g'){ char tmp_name[FILENAME_MAX]; sscanf(maintainer->buffer, "g %s", tmp_name); logger("<Server><process_command>get host info for file : %s\n", tmp_name); int i; for(i=0; i<MAX_FILES; ++i) if(!strcmp(tmp_name, maintainer->files[i].name)) break; if(i == MAX_FILES) return 0; int jth = time(NULL) % maintainer->files[i].num_of_owners; int j = 0; jth++; for(j = 0; j<MAX_CLIENTS ;++j){ if(maintainer->files[i].owners[j] != -1) jth--; if(jth == 0) break; } int k; for(k = 0 ; k<MAX_CLIENTS; k++) if(maintainer->clients[k].socket_fd == maintainer->files[i].owners[j]) break; /*maintainer->clients[k],node->curent_socket*/ bzero(maintainer->buffer, BUFFER_SIZE); sprintf(maintainer->buffer, "%s %d %d", tmp_name, maintainer->clients[k].ip, maintainer->clients[k].listening_port); logger("server responce is : %s\n", maintainer->buffer); logger("for this fd : %d\n", maintainer->clients[k].socket_fd); write(node->socket_fd, maintainer->buffer, BUFFER_SIZE); return 0; }else{ /*close_client_connection(maintainer, node->socket_fd, node, TRUE);*/ logger("<Server><process_command>got invalid command from client\n"); return 1; } return 0; }
/** * Entry point for threads to join the networking * stack. This method blocks indefinitely until the * network stack is shutdown. * @arg netconf The configuration for the networking stack. */ void start_networking_worker(hlld_networking *netconf) { // Allocate our user data worker_ev_userdata data; data.netconf = netconf; data.should_run = 1; data.inactive = NULL; // Allocate our pipe if (pipe(data.pipefd)) { perror("failed to allocate worker pipes!"); return; } // Create the event loop if (!(data.loop = ev_loop_new(netconf->ev_mode))) { syslog(LOG_ERR, "Failed to create event loop for worker!"); return; } // Set the user data to be for this thread ev_set_userdata(data.loop, &data); // Setup the pipe listener ev_io_init(&data.pipe_client, handle_worker_notification, data.pipefd[0], EV_READ); ev_io_start(data.loop, &data.pipe_client); // Setup the periodic timers, ev_timer_init(&data.periodic, handle_periodic_timeout, PERIODIC_TIME_SEC, 1); ev_timer_start(data.loop, &data.periodic); // Syncronize until netconf->threads is available barrier_wait(&netconf->thread_barrier); // Register this thread so we can accept connections assert(netconf->threads); pthread_t id = pthread_self(); for (int i=0; i < netconf->config->worker_threads; i++) { if (pthread_equal(id, netconf->threads[i])) { // Provide a pointer to our data netconf->workers[i] = &data; break; } } // Wait for everybody to be registered barrier_wait(&netconf->thread_barrier); // Run the event loop while (data.should_run) { ev_run(data.loop, EVRUN_ONCE); // Free inactive connections conn_info *c=data.inactive; while (c) { conn_info *n = c->next; close_client_connection(c); c = n; } data.inactive = NULL; } // Cleanup after exit ev_timer_stop(data.loop, &data.periodic); ev_io_stop(data.loop, &data.pipe_client); close(data.pipefd[0]); close(data.pipefd[1]); ev_loop_destroy(data.loop); }
void process__request() { int j, prslen ; int badval, count ; char rqlogmsg[120] ; char rqcmd[8] ; char rqstation[6] ; char rqlocation[4] ; char rqchannel[4] ; long rqyear, rqmonth, rqday, rqsamples ; int rqhour, rqmin, rqsec ; STDTIME2 rqstart ; int days_mth[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} ; /* Initialize log record and add request received message */ seqnum = 1 ; lgframes = 0 ; lgcount = 64 ; strcpy(lgstation_id, " "); for (j=lgcount; j<SEEDRECSIZE; j++) lgrec[j] = ' ' ; memcpy (rqlogmsg, "Request of \"", 12) ; cmdlen = strlen(incmdbuf) ; memcpy (&rqlogmsg[12], incmdbuf, cmdlen) ; j = cmdlen + 12 ; strcpy (&rqlogmsg[j], "\" received") ; add_log_message(rqlogmsg) ; /* Check for valid request keyword 'ASLREQ' or 'SER330' or 'RMSREQ' - if not, close connection to probers */ cmdcnt = 0 ; parse_request(' ') ; if (strcmp(prsbuf, "ASLREQ") != 0 && strcmp(prsbuf, "SER330") != 0 && strcmp(prsbuf, "RMSREQ") != 0) { close_client_connection() ; return ; } fprintf(stderr, "DEBUG msg '%s'\n", rqlogmsg); strncpy(rqcmd, prsbuf, 6); rqcmd[6] = 0; // Handle SER330 request seperately if (strcmp(prsbuf, "SER330") == 0) { process_ser330(); if (client_connected == 0) return; write_log_record(); return; } /* Parse and validate station name*/ ++cmdcnt ; parse_request('.') ; prslen = strlen(prsbuf) ; if (prslen < 3 || prslen > 5) { add_log_message("Invalid or missing station name") ; write_log_record() ; return ; } memcpy(lgstation_id, prsbuf, prslen + 1) ; memcpy(rqstation, prsbuf, prslen + 1) ; /* Parse and validate [location-]channel */ strcpy(rqlocation, " ") ; ++cmdcnt ; parse_request(' ') ; prslen = strlen(prsbuf) ; badval = 0 ; switch (prslen) { case 3 : memcpy(rqchannel, prsbuf, 4); break ; case 5 : if (prsbuf[1] == '-') { memcpy(rqlocation, prsbuf, 1) ; rqlocation[1] = 0; memcpy(rqchannel, &prsbuf[2], 4) ; } else badval = 1 ; break ; case 6 : if (prsbuf[2] == '-') { memcpy(rqlocation, prsbuf, 2) ; rqlocation[2] = 0; memcpy(rqchannel, &prsbuf[3], 4) ; } else badval = 1 ; break ; default : badval = 1 ; } if (badval == 1) { add_log_message("Invalid [location-]channel name") ; write_log_record() ; return ; } /* Parse and validate time of yyyy/mm/dd */ ++cmdcnt ; parse_request(' ') ; rqyear = 0 ; rqmonth = 0 ; rqday = 0 ; count = sscanf(prsbuf, "%ld/%ld/%ld", &rqyear, &rqmonth, &rqday) ; if (rqyear < 2005 || rqyear > 2050) badval = 1 ; if (rqmonth < 1 || rqmonth > 12) badval = 1 ; if (badval == 0) { if (rqyear % 4 == 0) days_mth[2] = 29 ; if (rqday < 1 || rqday > days_mth[rqmonth]) badval = 1 ; } if (badval == 1) { add_log_message("Invalid time yyyy/mm/dd") ; write_log_record() ; return ; } rqstart.year = rqyear ; /* Calculate days since beginning of year */ rqstart.day = 0 ; j = 0 ; while (j < rqmonth) { rqstart.day = rqstart.day + days_mth[j] ; ++j ; } rqstart.day = rqstart.day + rqday ; /* Parse and validate time of hh:mm:ss */ ++cmdcnt ; parse_request(' ') ; rqhour = 100 ; rqmin = 100 ; rqsec = 100 ; count = sscanf(prsbuf,"%d:%d:%d", &rqhour, &rqmin, &rqsec) ; if (rqhour < 0 || rqhour > 23) badval = 1 ; if (rqmin < 0 || rqmin > 59) badval = 1 ; if (rqsec < 0 || rqsec > 59) badval = 1 ; if (badval == 1) { add_log_message("Invalid time hh:mm:ss") ; write_log_record() ; return ; } rqstart.hour = rqhour ; rqstart.minute = rqmin ; rqstart.second = rqsec ; rqstart.tenth_msec = 0 ; /* Parse and validate number of samples */ ++cmdcnt ; parse_request(' ') ; rqsamples = 0 ; count = sscanf(prsbuf,"%ld", &rqsamples) ; if (rqsamples < 1 || rqsamples > MAXSAMPLES) { add_log_message("invalid number of samples") ; write_log_record() ; return ; } // Handle RMSREQ seperately if (strcmp(rqcmd, "RMSREQ") == 0) { process_rmsreq(rqstation, rqchannel, rqlocation, rqstart, rqsamples); if (client_connected == 0) return; write_log_record(); return; } /* Call the diskloop handler to find and send any available data Pass rqstation, rqlocation, rqchannel, rqstart, rqsamples */ TransferSamples(rqstation,rqchannel,rqlocation, rqstart, rqsamples); if (client_connected == 0) return ; if (seqnum == 1) add_log_message ("No data was available") ; else add_log_message ("Request for data was fufilled") ; write_log_record() ; } // process__reqeust()
int process_command(Maintainer* maintainer, Node* node) /*1 on close*/ { if(ENCRYPTION_ENABLED) { char encrypted[BUFFER_SIZE]; for(int i = 0 ; i < BUFFER_SIZE; ++i) encrypted[i] = node->read_msg.buffer[i]; if(private_decrypt(encrypted,BUFFER_SIZE,maintainer->private_key, node->read_msg.buffer) == -1) logger("<Server><process_command>Decryption failed\n"); } char command = node->read_msg.buffer[0]; char* msg = node->read_msg.buffer+1; if(command == 'a') { /*add file*/ logger("<Server><process_command>got add file command\n"); rb_red_blk_node* result = RBExactQuery(maintainer->files, msg); if(result == NULL) { int i=0; for(; i<32; ++i) if(msg[i] == '\0') break; ++i; char* file_name = mymalloc(i*sizeof(char)); for(int j=0; j<i; ++j) file_name[j]=msg[j]; File* new_file = mymalloc(sizeof(File)); strcpy(new_file->name, file_name); new_file->num_of_owners = 0; new_file->owners = mymalloc(sizeof(struct Nodes_ll)); new_file->owners->next = NULL; new_file->owners->node = node; result = RBTreeInsert(maintainer->files, file_name, new_file); } ((File*)(result->info))->num_of_owners++; struct Nodes_ll* owners_head = ((File*)(result->info))->owners; while(owners_head != NULL) if(owners_head->node == node) return 0; else owners_head = owners_head->next; owners_head = mymalloc(sizeof(struct Nodes_ll)); owners_head->next=((File*)(result->info))->owners; ((File*)(result->info))->owners = owners_head; owners_head->node = node; return 0; } else if(command == 'q') { logger("<Server><process_command>got close connection command\n"); close_client_connection(maintainer, node->socket_fd, node, FALSE); return 1; } else if(command == 'd') { logger("<Server><process_command>got delete file command\n"); rb_red_blk_node* founded_node = RBExactQuery(maintainer->files, msg); File* this_file = founded_node->info; struct Nodes_ll* owners_head = this_file->owners; struct Nodes_ll* prev = this_file->owners; while(owners_head != NULL) { if(owners_head->node == node) { prev->next = owners_head->next; this_file->num_of_owners--; if(owners_head == this_file->owners) this_file->owners = this_file->owners->next; myfree(owners_head); break; } if(prev != owners_head) { prev = owners_head; owners_head = owners_head->next; } } return 0; } else if(command == 'l') { sscanf(msg, "%d", &(node->listening_port)); logger("<Server><process_command>got listening port as %d\n", node->listening_port); return 0; } else if(command == 'p') { for(int i=0; i<(BUFFER_SIZE-1); ++i) node->pubkey[i] = msg[i]; logger("<Server><process_command>got the first part of clients pubkey\n"); return 0; } else if(command == 'k') { for(int i=(BUFFER_SIZE-1); i<PUBKEY_SIZE; ++i) node->pubkey[i] = msg[i-BUFFER_SIZE+1]; logger("<Server><process_command>got the second part of clients pubkey\n"); return 0; } else if(command == 'g') { if(node->write_msg.offset != 0) return 1; /*get host info*/ char* file_name = mymalloc(32); sscanf(msg,"%s",file_name); logger("<Server><process_command>get host info for file : %s\n", file_name); rb_red_blk_node* founded_node = RBExactQuery(maintainer->files, file_name); if(founded_node == NULL) { node->write_msg.buffer[0] = 'n'; strcpy(node->write_msg.buffer+1, file_name); if(ENCRYPTION_ENABLED) encrypt_for_client(node->write_msg.buffer, node->pubkey); FD_SET(node->socket_fd, &(maintainer->fd_write_set)); return 0; } int rand_num = myrand()%((File*)(founded_node->info))->num_of_owners; struct Nodes_ll* return_info = ((File*)(founded_node->info))->owners; int i=0; while(i<rand_num) { ++i; return_info = return_info->next; } char* token = mymalloc(8*sizeof(char)); for(i=0; i<7; ++i) token[i] = myrand()%100+20; /*print output*/ token[7]='\0'; logger("<Server><process_command>generated token : %s\n", token); RBTreeInsert(return_info->node->requests, file_name, token); int write_size = sprintf(node->write_msg.buffer, "h%d:%d %s %s", return_info->node->ip, return_info->node->listening_port, file_name, token); node->write_msg.total_len = BUFFER_SIZE; if(write_size == BUFFER_SIZE) { node->write_msg.total_len = 0; return 1; } else if((node->pubkey[0] != '\0') && ENCRYPTION_ENABLED) { for(i=write_size; i<(BUFFER_SIZE); ++i) node->write_msg.buffer[i] = node->pubkey[i-write_size]; node->write_msg.dual_msg = TRUE; node->write_msg.extended_buffer = mymalloc(BUFFER_SIZE); node->write_msg.extended_buffer[0]='i'; for(i=0; i<(PUBKEY_SIZE-BUFFER_SIZE+write_size); ++i) node->write_msg.extended_buffer[i+1] = node->pubkey[i+BUFFER_SIZE-write_size]; if(ENCRYPTION_ENABLED) { encrypt_for_client(node->write_msg.buffer, node->pubkey); encrypt_for_client(node->write_msg.extended_buffer, node->pubkey); } } FD_SET(node->socket_fd, &(maintainer->fd_write_set)); return 0; } else if(command == 'c') { int request_from_ip; char request_file_name[32]; char request_token[8]; /*change this in client side*/ sscanf(msg, "%s %d %s", request_file_name, &request_from_ip, request_token); logger("<Server><process_command>checking credentials : %s %d %s\n", request_file_name, request_from_ip, request_token); rb_red_blk_node* node_from = RBExactQuery(maintainer->nodes_ip, &request_from_ip); node->write_msg.total_len=BUFFER_SIZE; if(node_from == NULL) { sprintf(node->write_msg.buffer, "f%s", request_token); } else { rb_red_blk_node* request_rb_node = RBExactQuery(((Node*)(node_from->info))->requests, request_file_name); if(request_rb_node == NULL) sprintf(node->write_msg.buffer, "f%s", request_token); else { if(strcmp((char*)(request_rb_node->info),request_token)) sprintf(node->write_msg.buffer, "f%s", request_token); else { sprintf(node->write_msg.buffer, "o%s", request_token); logger("<Server><process_command>and it is ok\n"); } } } if(ENCRYPTION_ENABLED) encrypt_for_client(node->write_msg.buffer, node->pubkey); FD_SET(node->socket_fd, &(maintainer->fd_write_set)); } else { /*close_client_connection(maintainer, node->socket_fd, node, TRUE);*/ logger("<Server><process_command>got invalid command from client\n"); return 1; } return 0; }
int main(int argc , char *argv[]) { Maintainer* maintainer = mymalloc(sizeof(Maintainer)); init_maintainer(maintainer); logger("<Server><main>maintainer initialized\n"); int opt = TRUE; if((maintainer->master_socket=socket(AF_INET, SOCK_STREAM, 0))==0) { logger("<Server><main>failed at master socket creation\n"); myfree(maintainer); exit(EXIT_FAILURE); } fcntl(maintainer->master_socket, F_SETFL, O_NONBLOCK); if(setsockopt(maintainer->master_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)) < 0) { logger("<Server><main>failed at master socket reuse\n"); myfree(maintainer); exit(EXIT_FAILURE); } if(bind(maintainer->master_socket, (struct sockaddr *)&(maintainer->address), sizeof(maintainer->address)) < 0) { logger("<Server><main>failed at master socket binding\n"); myfree(maintainer); exit(EXIT_FAILURE); } if (listen(maintainer->master_socket, 10) < 0) { logger("<Server><main>failed at master socket listen"); exit(EXIT_FAILURE); } FD_SET(maintainer->master_socket, &(maintainer->fd_read_set)); FD_SET(maintainer->master_socket, &(maintainer->fd_exception_set)); maintainer->max_sd = maintainer->master_socket; while(TRUE) { maintainer->fd_read_set_select = maintainer->fd_read_set; maintainer->fd_write_set_select = maintainer->fd_write_set; maintainer->fd_exception_set_select = maintainer->fd_exception_set; if ((select(maintainer->max_sd+1, &(maintainer->fd_read_set_select), &(maintainer->fd_write_set_select), &(maintainer->fd_exception_set_select), NULL) < 0)) logger("<Server><main>error at select\n"); if (FD_ISSET(maintainer->master_socket, &(maintainer->fd_read_set_select))) handle_new_client(maintainer); if (FD_ISSET(maintainer->master_socket, &(maintainer->fd_exception_set_select))) handle_server_exception(maintainer); struct Nodes_ll* prev = maintainer->clients; struct Nodes_ll* iterator = maintainer->clients; while(iterator != NULL) { int current_socket = iterator->node->socket_fd; if(FD_ISSET(current_socket, &(maintainer->fd_exception_set_select))) close_client_connection(maintainer, current_socket, iterator->node, TRUE); else if(FD_ISSET(current_socket, &(maintainer->fd_read_set_select))) if(!read_from_client(maintainer, current_socket, iterator->node)) if(FD_ISSET(current_socket, &(maintainer->fd_write_set_select))) write_to_client(maintainer, current_socket, iterator->node); else if(FD_ISSET(current_socket, &(maintainer->fd_write_set_select))) write_to_client(maintainer, current_socket, iterator->node); if(iterator != maintainer->clients) { if(iterator->node->socket_fd == -1) { prev->next = iterator->next; myfree(iterator->node); struct Nodes_ll* tmp = iterator; iterator = iterator->next; myfree(tmp); } else { prev = prev->next; iterator = iterator->next; } } else if(iterator->node->socket_fd == -1) { /*marked for deletation*/ maintainer->clients = iterator->next; myfree(iterator->node); struct Nodes_ll* tmp = iterator; iterator = iterator->next; myfree(tmp); } else iterator = iterator->next; } } myfree(maintainer); return 0; }