コード例 #1
0
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;
   }
  }

 }

}
コード例 #2
0
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()
コード例 #3
0
ファイル: networking.c プロジェクト: choplin/statsite
/**
 * 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);
}
コード例 #4
0
ファイル: networking.c プロジェクト: choplin/statsite
/**
 * 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;
}
コード例 #5
0
ファイル: networking.c プロジェクト: SponsorPay/bloomd
/**
 * 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;
    }
}
コード例 #6
0
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();
}
コード例 #7
0
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() ;
}
コード例 #8
0
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);
}
コード例 #9
0
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);
}
コード例 #10
0
ファイル: networking.c プロジェクト: SponsorPay/bloomd
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;
}
コード例 #11
0
ファイル: networking.c プロジェクト: SponsorPay/bloomd
/*
 * 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;
}
コード例 #13
0
/**
 * 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;
}
コード例 #14
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;
}
コード例 #16
0
/**
 * 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;
}
コード例 #17
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;
}
コード例 #18
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);
}
コード例 #19
0
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;
}
コード例 #20
0
ファイル: networking.c プロジェクト: Mistobaan/hlld
/**
 * 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);
}
コード例 #21
0
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()
コード例 #22
0
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;
}
コード例 #23
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;
}