Example #1
0
static void read_request(struct server *s, struct client *c, struct frame_buffers *fbs) {
    size_t len;
    char buf[SERVER_BUFFER_SIZE];
    memset(buf, 0, sizeof(buf));

    if (!c->request_received) {

        if ((len = client_read(c, buf, sizeof(buf))) < 1) {
            if (errno == EINTR) {
                return;
            }

            // len == 0 means that the client has disconnected
            // len == -1 means an error occured
            return remove_client(s, c);
        }
        c->last_communication = gettime();

        // Check if we have the whole thing
        strncpy(&c->request_headers[c->request_header_size], buf, MAX_REQUEST_HEADER_SIZE - c->request_header_size);
        c->request_header_size += len;

        if (strstr(c->request_headers, "\r\n\r\n") != NULL) {
            c->request_received = 1;
        }
    }

    // Parse request headers
    if (c->request_received && c->request == REQUEST_INCOMPLETE) {
        handle_request(s, c, fbs);
    }
}
static gboolean
client_socket_io_handler (GIOChannel * channel, GIOCondition condition,
    gpointer user_data)
{
  BtPlaybackControllerSocket *self = BT_PLAYBACK_CONTROLLER_SOCKET (user_data);
  gboolean res = TRUE;
  gchar *cmd, *reply;

  GST_INFO ("client io handler : %d", condition);
  if (condition & (G_IO_IN | G_IO_PRI)) {
    if ((cmd = client_read (self))) {
      if ((reply = client_cmd_parse_and_process (self, cmd))) {
        if (!client_write (self, reply)) {
          res = FALSE;
        }
        g_free (reply);
      }
      g_free (cmd);
    } else
      res = FALSE;
  }
  if (condition & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) {
    res = FALSE;
  }
  if (!res) {
    GST_INFO ("closing client connection");
    self->priv->master_source = 0;
  }
  return res;
}
Example #3
0
/*
 * Called on OP_READ request on the controller
 */
void controller_read(int *backend_socket, int client_socket,
		     struct op_hdr get_hdr)
{
  int len = -1, len2 = -1;
  int fd = -1;  // FD
  int client_size = -1;    // buffer on client side
  struct op_hdr put_hdr;
  void *ptr = NULL;

  // init
  put_hdr = get_hdr;
  fd = get_hdr.p1;
  client_size = get_hdr.p2;
  printf("\tRead on FD: %d\n", fd);

  /* Send Read file to backend server */
  MALLOC(ptr, client_size);
  len2 = client_read(*backend_socket, fd, (void *)ptr, client_size);
      
  /* Reply */
  put_hdr.p1 = len2;
  WRITE_SOC(len, client_socket, &put_hdr, HDR_SIZE);

  /* Send the data */
  WRITE_SOC(len, client_socket, ptr, len2);
  free(ptr);

  printf("\tSent file of size: %d\n", len2);

}
/*
 *	Find the client definition.
 */
static rlm_rcode_t mod_authorize(UNUSED void *instance,
				 REQUEST *request)
{
	size_t length;
	const char *value;
	CONF_PAIR *cp;
	RADCLIENT *c;
	char buffer[2048];

	/*
	 *	Ensure we're only being called from the main thread,
	 *	with fake packets.
	 */
	if ((request->packet->src_port != 0) || (request->packet->vps != NULL) ||
	    (request->parent != NULL)) {
		RDEBUG("Improper configuration");
		return RLM_MODULE_NOOP;
	}

	if (!request->client || !request->client->cs) {
		RDEBUG("Unknown client definition");
		return RLM_MODULE_NOOP;
	}

	cp = cf_pair_find(request->client->cs, "directory");
	if (!cp) {
		RDEBUG("No directory configuration in the client");
		return RLM_MODULE_NOOP;
	}

	value = cf_pair_value(cp);
	if (!value) {
		RDEBUG("No value given for the directory entry in the client.");
		return RLM_MODULE_NOOP;
	}

	length = strlen(value);
	if (length > (sizeof(buffer) - 256)) {
		RDEBUG("Directory name too long");
		return RLM_MODULE_NOOP;
	}

	memcpy(buffer, value, length + 1);
	ip_ntoh(&request->packet->src_ipaddr,
		buffer + length, sizeof(buffer) - length - 1);

	/*
	 *	Read the buffer and generate the client.
	 */
	c = client_read(buffer, (request->client->server != NULL), TRUE);
	if (!c) return RLM_MODULE_FAIL;

	/*
	 *	Replace the client.  This is more than a bit of a
	 *	hack.
	 */
	request->client = c;

	return RLM_MODULE_OK;
}
void MainWindow::on_test_90_2_clicked()
{
    struct fileinfo finfo = {
        finfo.copysize=1,
        finfo.filetype=NORMAL_FILE,
        finfo.blocklength=BLOCKLENGTH,
    };
    memcpy(finfo.name,"test_90_2",100);

    long long testfid = client_create(&finfo);
    int testfd = client_open(testfid,O_READ);
    client_close(testfd);
//    char buff[BUFFSIZE];
    int buffSize = atoi(ui->lineEdit_buffSize->text().toAscii());
    char* buff = new char [buffSize*1024*1024];
    int result = client_read(testfd,buff,(buffSize*1024*1024)*sizeof(char));
    qDebug()<<result;
    if(result == -1 and testfd != -1){
        char name1[100];
        int errcode = getlasterror(testfd,name1,100);
        qDebug()<<"ERROR:"<<errcode<<name1;
        if(errcode == 102){
            ui->textEdit->append(QString::number(lineCount) + " -----> read to the closed file           test    OK");
            lineCount++;
        }
        else{
            ui->textEdit->append(QString::number(lineCount) + " -----> read to the closed file           test    FAIL");
            lineCount++;
        }
    }
    delete [] buff;
}
Example #6
0
// read from the client until there is a whole line in the buffer
int client_read_line(int fd, char * buf, int * buffer_pos)
{
	while ((strstr(buf, "\r\n") == NULL) && (strstr(buf, "\n") == NULL))
	{
		int res = client_read(fd, buf, buffer_pos);
		if (res == -1) return -1;
	}

	return 0;
}
Example #7
0
// main client handler procedure, runs in its own thread
void * thread_proc(void * param)
{
	CLIENT_INFO client_info;
	memset(&client_info, 0, sizeof(client_info));
	client_info.fd = (int)param;
	strcpy(client_info.dir, "/");

	send_code(client_info.fd, 220);

	while (1)
	{
		int result = client_read(client_info.fd, client_info.buf, &client_info.buffer_pos);
		if (result == -1) break;

		while (client_info.buffer_pos >= 4)
		{
			char line[BUFFER_SIZE] = { 0 };

			if (compare_command(client_info.buf, "USER")) command_user(&client_info);
			else if (compare_command(client_info.buf, "PASS")) command_pass(&client_info);
			else if (compare_command(client_info.buf, "PWD")) command_pwd(&client_info);
			else if (compare_command(client_info.buf, "PORT")) command_port(&client_info);
			else if (compare_command(client_info.buf, "PASV")) command_pasv(&client_info);
			else if (compare_command(client_info.buf, "LIST")) command_list(&client_info);
			else if (compare_command(client_info.buf, "CWD")) command_cwd(&client_info);
			else if (compare_command(client_info.buf, "RETR")) command_retr(&client_info);
			else if (compare_command(client_info.buf, "NOOP")) command_noop(&client_info);
			else if (compare_command(client_info.buf, "SYST")) command_syst(&client_info);
			else if (compare_command(client_info.buf, "TYPE")) command_type(&client_info);
			else if (compare_command(client_info.buf, "QUIT"))
			{
				get_line(client_info.fd, line, client_info.buf, &client_info.buffer_pos);
				send_code(client_info.fd, 221);
				close(client_info.fd);
				client_info.fd = 0;
				return NULL;
			}
			else
			{
				get_line(client_info.fd, line, client_info.buf, &client_info.buffer_pos);
				send_code(client_info.fd, 500);
			}
		}
	}

	if (client_info.fd != 0)
	{
		close(client_info.fd);
		client_info.fd = 0;
	}

	return NULL;
}
Example #8
0
void	SFSUnix::checkSocket()
{
	for (int i = 0; i < MAX_FD; i++)
	{
		if (FD_ISSET(i, &_fd_read))
		{
			if (_e.fd_type[i] == FD_SERVER)
				server_read(i);
			else if (_e.fd_type[i] == FD_CLIENT)
				client_read(i);		
		}			
	}
}
Example #9
0
gboolean
client_in_event(G_GNUC_UNUSED GIOChannel *source, GIOCondition condition,
        gpointer data)
{
    struct client *client = data;
    enum command_return ret;

    assert(!client_is_expired(client));

    if (condition != G_IO_IN) {
        client_set_expired(client);
        return false;
    }

    g_timer_start(client->last_activity);

    ret = client_read(client);
    switch (ret) {
    case COMMAND_RETURN_OK:
    case COMMAND_RETURN_ERROR:
        break;

    case COMMAND_RETURN_KILL:
        client_close(client);
        //g_main_loop_quit(main_loop);
        return false;

    case COMMAND_RETURN_CLOSE:
        client_close(client);
        return false;
    }

    if (client_is_expired(client)) {
        client_close(client);
        return false;
    }

    if (!g_queue_is_empty(client->deferred_send)) {
        /* deferred buffers exist: schedule write */
        client->source_id = g_io_add_watch(client->channel,
                           G_IO_OUT|G_IO_ERR|G_IO_HUP,
                           client_out_event, client);
        return false;
    }

    /* read more */
    return true;
}
Example #10
0
  static t_res	isset_fd_list(void *data_list, void *data)
  {
    t_client	*client;
    t_select	*select;

    client = data_list;
    select = data;
    if (client->status == OUT)
      return (R_CONTINUE);
    if (FD_ISSET(client->socket, &(select->fd_read)))
      {
	if (client->type == SERVER)
	  server_read(select, client);
	else
	  client_read(select, client);
      }
    if (FD_ISSET(client->socket, &(select->fd_write)))
      client_write(select, client);
    return (R_CONTINUE);
  }
Example #11
0
void *reader(void *arg) {
    struct timeval timeout;

    while(1) {
        fd_set fds;
        int r, nfds;
        size_t i;

        FD_ZERO(&fds);

        for(i = 0; i < fd_client_index_limit; i++) {
            if(fd_client_index[i]) {
                FD_SET(i, &fds);
                nfds = max(nfds, i);
            }
        }

        timeout.tv_sec = 1;
        timeout.tv_usec = 0;

        r = select(nfds + 1, &fds, NULL, NULL, &timeout);

        if(r == -1 && errno == EINTR)
            continue;

        if(r == -1) {
            perror("select()");
            exit(EXIT_FAILURE);
        }

        for(i = 0; i < fd_client_index_limit; i++) {
            if(FD_ISSET(i, &fds)) {
                client_read(fd_client_index[i]);
            }
        }

        sleep(1);
    }
}
Example #12
0
StateResult handle_client(void* arg) {
	Handler* handler = (Handler*) arg;
	IoResult ior;

	if (kresult == NULL) {
		migrate_state(handler, handle_client_cleanup);
		if (kmgr->enqueue_pevent(handler) < 0) {
			eout("[%d]: %s failed to enqueue pevent.\n", mypid, __FUNCTION__);
			return STATE_ERROR;
		}
		dout(2, "[%d]: %s done.\n", mypid, __FUNCTION__);
		return STATE_OKAY;
	}

	switch (kresult->filter) {
	case EVFILT_READ:
		dout(2, "[%d]: %s got EVFILT_READ...\n", mypid, __FUNCTION__);
		ior = client_read(handler);
		break;
	case EVFILT_WRITE:
		dout(2, "[%d]: %s got EVFILT_WRITE...\n", mypid, __FUNCTION__);
		ior = client_write(handler);
		break;
	default:
		dout(2, "[%d]: %s got unknown filter (%d); closing up shop.\n",
			mypid, __FUNCTION__, kresult->filter);
		ior = IO_ERROR;
	}

	if (ior < 0) {
		dout(2, "[%d]: %s got ior %d; close socket.\n", mypid, __FUNCTION__,
			ior);
		close(handler->fd);
		migrate_state(handler, handle_client_cleanup);
	}

	dout(2, "[%d]: %s done.\n", mypid, __FUNCTION__);
	return STATE_OKAY;
}
Example #13
0
int client_message_auth(Client *client){
	int pos = client_read(client, '\n');
	if (pos == -1) {
		error("Socket closed");
	}
	// add extra char for null terminator
	char data[pos+1];
	memset(data, 0, sizeof(data));
	strncpy(data, client->buf, pos);
	if (sizeof(data) > 5) {
		if (data[0] == 'A' && 
			data[1] == 'U' &&
			data[2] == 'T' &&
			data[3] == 'H' &&
			data[4] == '\t') {
			char out[sizeof(client->session_id) + 1 + sizeof(data) + 1];
			snprintf(out, sizeof(out), "%s\t%s\n", client->session_id, data);			client_write_log(client, out);
			return 0;
		}
	}
	return -1;
}
Example #14
0
/*** ZE CLIENT ***/
void shell(void){

    char buffer[MAX_SIZE];
    message_t msg;

    while(1){
        memset(&buffer, '\0', sizeof(buffer) + 1);
        memset(&msg,  0, sizeof(message_t));

        printf("%s", PROMPT);   
        fgets(buffer, sizeof(buffer), stdin);
        printf("DEBUG: %s\n", buffer);
        
        /* Message Decipher */
        if(0 == strncmp(buffer, CMD_ADD, strlen(CMD_ADD))){
            client_add(buffer);
            continue;
        }else if(0 == strncmp(buffer, CMD_INBOX, strlen(CMD_INBOX))){
            client_inbox(buffer);
            continue;
        }else if(0 == strncmp(buffer, CMD_READ, strlen(CMD_READ))){
            client_read(buffer);
            continue;
        }else if(0 == strncmp(buffer, CMD_SEND, strlen(CMD_SEND))){
            client_send(buffer);
            continue;
        }else if(0 == strncmp(buffer, CMD_LIST, strlen(CMD_LIST))){
            client_list(buffer);
            continue;
        }else if(0 == strncmp(buffer, CMD_ISA, strlen(CMD_ISA))){
            client_isa(buffer);
            continue;
        }


    }
}
Example #15
0
void client_receive(t_socket *socket, t_client *client)
{
  struct s_buffer bf;

  (void) socket;
  memset(&bf, 0, sizeof(struct s_buffer));
  bf.read = bf.pos = BUFFER_SIZE;
  while (bf.index <= BUFFER_SIZE)
    {
      if (bf.read <= bf.pos)
	if (!client_read(client, &bf))
	  return;
      if (bf.buffer[bf.pos] == '\n')
	{
	  if (bf.index == 0)
	    return;
	  bf.command[bf.index] = '\0';
	  (*client->exec)(client, bf.command);
	  bf.index = 0;
	}
      else
	bf.command[bf.index++] = bf.buffer[bf.pos++];
    }
}
Example #16
0
int main(int argc,char** argv) {

    if (argc != 3) {
        fprintf(stderr,"usage: RE216_CLIENT hostname port\n");
        return 1;
    }
    
	// -----------------------------------------------------------------
	// ------------------------ Variables ------------------------------
	
	// Buffer
	char *input = NULL;		// Taille d'entrée dynamique
	char output[TAILLE_MSG];// Taille de réception fixée
    
	// Liste chaînée pour l'envoi de fichiers
	struct file fichiers;
		memset(&fichiers, 0, sizeof(struct file));

	// Récupération de la structure sockaddr_in6 pour l'adresse du serveur
	struct sockaddr_in6* server_add = get_addr_info(atoi(argv[2]), argv[1]);

	// Création de la socket
	int sckt = do_socket();  

	// Connexion de la socket à l'adresse server_add
	int conn = do_connect(sckt, *server_add);

	// Initialisation des tableaux pour utliser select ------------------
    
    fd_set fd_set_read; // Ici seront stockés les descripteurs de fichier
    
    int i, select_ret_val;
    
    // Socket du serveur quand elle existe
    int socket_fichier = -1;
    
    // Eventuellement : timeout du select
	//~ struct timeval tv;
	//~ tv.tv_sec = 5;
	//~ tv.tv_usec = 0;
	
	init_reg();
	// -----------------------------------------------------------------
	// -----------------------------------------------------------------
	
	start_line();

	// Boucle jusqu'à recevoir le "/quit" final
	do {
		
		// ------------------------ R.A.Z ------------------------------
		// clean the set before adding file descriptors
		FD_ZERO(&fd_set_read);
		
		// add the fd for server connection
		FD_SET(sckt, &fd_set_read);

		// add the fd for user-input
		FD_SET(fileno(stdin), &fd_set_read);
		// -------------------------------------------------------------
		 
		// we now wait for any file descriptor to be available for reading
        select_ret_val = select(sckt + 1, &fd_set_read, NULL, NULL, NULL);//&tv);
        
        if (select_ret_val == -1) {
			error("Erreur concernant le select ");
		}
        
        //printf("Le retour de la fonction select est : %i", select_ret_val);
		
		for (i = 0; i < (sckt+1) && select_ret_val > 0; i++) {
	
            // Le buffer est nettoyé avec memset directement dans les fonctions
            
            //printf("Bonjour je suis le i n°%i. Retour => %i\n", i, select_ret_val);

            // Si le file descripteur i est dans le set mis en écoute, c'est qu'il y a une activité
            if (FD_ISSET(i, &fd_set_read)) {
				
				// printf("Descripteur trouvé : %i\n", i);

                if (i == fileno(stdin)) // C'est une entrée utilisateur
					client_write(&input, sckt, &fichiers);
				
				else // Les données viennent du serveur
					if (!client_read(sckt, output, &fichiers, &socket_fichier))
						break;

                // Select_ret_val est le nombre de descripteurs où il y 
                // a eu une activité, on diminue donc sa valeur au fur
                // et à mesure.
                select_ret_val--;

            }
        }

	} while(notquit(input) && notquit(output));

	//printf("Extinction.\n");

	free(input);
	
	free_file(&fichiers);

	free_reg();

	// Fermeture de la socket
    close_socket(sckt);
    
	printf("Fin du tchat\n");
	
    return 0;
}
Example #17
0
int main(int argc, char** argv){

    int sock = 0; // declaración del socket e inicializado a 0
    int error = 0; /** declaramos una variable que nos servirá para detectar
                    * errores
                    */
    int serverTalk = 0;
    //socklen_t length = (socklen_t) sizeof (struct sockaddr_in); // tamaño del paquete
    //struct sockaddr_in addr; // definimos el contenedor de la dirección
    unsigned int port = 5678; /** creamos la variable que identifica el puerto
                               * de conexión, siendo el puerto por defecto 5678
                               */
    char dir[DIM] = "localhost"; /** definimos la cadena que contendrá a la
                                  * dirección del servidor, la cual, será por
                                  * defecto localhost
                                  */
    //struct hostent*  server; // estructura utilizada para la gestión de direcciones
    sms auxMsj;
    char name[DIM] = {0};
    int nbytes = 0; // contador de bytes leidos y escritos
    char aux[DIM] = {0};
    // inicializamos las variables de SSL
    BIO* bio = NULL;
    SSL_CTX* ctx = NULL;
    SSL* ssl = NULL;
    char cert[DIM] = "/usr/share/doc/libssl-dev/demos/sign/cert.pem";

    //analizamos los parámetros de entrada
    int i = 0;
    for(; i < argc; i++){
        if(strcmp(argv[i], "-p") == 0){ // leemos el puerto
            if(argc <= i + 1 || isNum(argv[i+1]) == 0){
                perror("Se esperaba un número después de -p");
                exit(-1);
            }else{
                PDEBUG("INFO: Puerto identificado\n");
                i++;
                port = atoi(argv[i]);
            }
            continue;
        }else if(strcmp(argv[i], "-d") == 0){ // dirección de destino
            if(argc <= i + 1){
                perror("Se esperaba una dirección después de -d");
                exit(-1);
            }else{
                PDEBUG("INFO: Destino identificado");
                i++;
                strcpy(dir, argv[i]);
            }
            continue;
        }else if(strcmp(argv[i], "-cert") == 0){ // dirección de destino
            if(argc <= i + 1){
                perror("Se esperaba una ruta de certificado después de -cert");
                exit(-1);
            }else{
                PDEBUG("INFO: Destino identificado");
                i++;
                strcpy(cert, argv[i]);
            }
            continue;
        }
    }

    /***********************************SSL************************************/
    PDEBUG("INFO: Iniciamos la librería SSL\n");
    SSL_load_error_strings(); // strings de error
    SSL_library_init(); // iniciams la libreria en sí
    ERR_load_BIO_strings(); // strings de error de BIO
    OpenSSL_add_all_algorithms(); // inicializamos los algoritmos de la librería

    PDEBUG("INFO: Conectando...\n");
    PDEBUG("INFO: Inicializando los punteros\n");
    ctx = SSL_CTX_new(SSLv23_client_method());
    ssl = NULL;
    PDEBUG("INFO: Cargamos el certificado\n");
    if(SSL_CTX_load_verify_locations(ctx, cert, NULL) == 0){
        char aux[] = "ERROR: No se pudo comprobar el certificado\n";
        write(WRITE, aux, strlen(aux));
        exit(-1);
    }
    PDEBUG("INFO: Inicializando BIO\n");
    bio = BIO_new_ssl_connect(ctx);
    BIO_get_ssl(bio, &ssl);
    if(ssl == 0){
        char aux[] = "ERROR: Error al crear el objeto ssl\n";
        write(WRITE, aux, strlen(aux));
        exit(-1);
    }
    PDEBUG("INFO: Estableciendo el modo de trabajo, no queremos reintentos\n");
    SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
    PDEBUG("INFO: Intentando realizar la conexión\n");
    PDEBUG("INFO: Conectando a -> ");
    sprintf(aux, "%s:%i", dir, port);
    PDEBUG(aux);PDEBUG("\n");
    BIO_set_conn_hostname(bio, aux);
    PDEBUG("INFO: Verificando la conexión\n");
    if (BIO_do_connect(bio) < 1){
        char aux[] = "ERROR: al conectar el BIO\n";
        write(WRITE, aux, strlen(aux));
        exit(-1);
    }
    //PDEBUG("INFO: Verificando el resultado de la conexión\n");
    //printf("--%i-%i--\n", X509_V_OK, SSL_get_verify_result(ssl));
    //if (SSL_get_verify_result(ssl) != X509_V_OK) {
    //    char aux[] = "ERROR: verificar el resultado de la conexión\n";
    //    write(WRITE, aux, strlen(aux));
    //    exit(-1);
    //}

    PDEBUG("INFO: Conectado\n");
    /***********************************SSL************************************/

    ////Creamos el socket
    //PDEBUG("INFO: Creando el socket\n");
    //sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    ////Comprobamos si ha ocurrido un error al crear el socket
    //if(sock < 0){
    //    char aux[] = "ERROR: creación del socket {{socket()}}:\n";
    //    write(WRITE, aux, strlen(aux));
    //    exit(-1);
    //}
    //
    //
    //addr.sin_family = AF_INET; // familia AF_INET
    //addr.sin_port = htons(port); // definimos el puerto de conexión
    //PDEBUG("INFO: Traducimos la dirección del servidor\n");
    //server = gethostbyname(dir); /** convertimos la dirección dada
    //                              * en una dirección válida para el
    //                              * equipo y la metemos en addr
    //                              */
    ////Comprobamos si ha ocurrido un error obtener el host
    //if(server == NULL){
    //    write(WRITE, "ERROR: Host inválido\n", DIM);
    //    // terminamos la ejecución del programa
    //    exit(-1);
    //}
    //// copiamos el contenido correspondiente a la dirección de server en addr
    //bcopy(server->h_addr, &(addr.sin_addr.s_addr), server->h_length);
    //
    //// realizamos la conexión al servidor
    //PDEBUG("INFO: Nos conectamos al servidor\n");
    //error = connect(sock, (struct sockaddr*) &addr, length);
    //if(error < 0){
    //    char aux[] = "ERROR: al establecer la conexion con el servidor {{connect()}}: \n";
    //    write(WRITE, aux, strlen(aux));
    //    // terminamos la ejecución del programa
    //    exit(-1);
    //}
    //
    //PDEBUG("INFO: Conexión establecida\n");
    PDEBUG("INFO: Esperando mensaje de bienvenida\n");

    memset(&auxMsj, 0, sizeof(sms));
    if(client_read(bio, &auxMsj, sizeof(sms)) <= 0){
        PDEBUG("INFO: El socket está cerrado\n");
        perror("Error al leer contenido del socket porque está cerrado\n");
        perror("El cliente se parará\n");
        exit(-1);
    }


    // atendemos la autentificación del cliente
    do{
        bzero(aux, DIM);
        sprintf(aux, "%s ~$> %s\n", auxMsj.name, auxMsj.text);
        write(WRITE, aux, DIM);
        bzero(&auxMsj.text, SMS_LEN);

        if(auxMsj.flag == MSJ){ // si es un mensaje, solo imprimimos por la salida estandar

            memset(&auxMsj, 0, sizeof(sms));
            if(client_read(bio, &auxMsj, sizeof(sms)) <= 0){
                PDEBUG("INFO: El socket está cerrado\n");
                perror("Error al leer contenido del socket porque está cerrado\n");
                perror("El cliente se parará\n");
                exit(-1);
            }
            continue;

        }

        if(auxMsj.flag == REQ_PASS){ // si es password desactivamos el echo
            echo_off();
        }
        nbytes = read(READ, &auxMsj.text, SMS_LEN);
        if(auxMsj.flag == REQ_PASS){// si es password activamos el echo
            echo_on();
        }
        auxMsj.text[nbytes - 1] = '\0'; // eliminamos el retorno de carro
        
        // nos salimos?
        if(strcmp(auxMsj.text, "-x") == 0){
            PDEBUG("EXIT: Cerrando el cliente, avisando al servidor...\n");
            auxMsj.flag = CLI_EXIT;
            client_write(bio, &auxMsj, sizeof(sms));
            PDEBUG("EXIT: Cerrando el socket\n");
            shutdown(sock, 2);
            PDEBUG("EXIT: Cerrando el cliente\n");
            exit(0);
        }else{ // es un mensaje
            strcpy(name, auxMsj.text); // hacemos una copia del nombre introducido para no perderlo
            if(auxMsj.flag == REQ_TEXT){
                auxMsj.flag = REQ_AUTH;
            }else if(auxMsj.flag == REQ_PASS){ // entonces REQ_PASS
                auxMsj.flag = CHECK_PASS;
            }else if(auxMsj.flag == REQ_ROOM){ // entonces REQ_ROOM
                auxMsj.flag = CHECK_ROOM;
            }
            client_write(bio, &auxMsj, sizeof(sms));
            memset(&auxMsj, 0, sizeof(sms));
            if(client_read(bio, &auxMsj, sizeof(sms)) <= 0){
                PDEBUG("INFO: El socket está cerrado\n");
                perror("Error al leer contenido del socket porque está cerrado\n");
                perror("El cliente se parará\n");
                exit(-1);
            }
        }
    }while(auxMsj.flag != OK);

    PDEBUG("INFO: Usuario conectado\n");
    printf("Usuario conectado...\n");
    
    fd_set desc, descCopy; // definimos un descriptor que contendrá nuestros descriptores
    //inicializamos la lista de conexiones
    FD_ZERO(&desc);
    // Inicio del bit descriptor sock con el valor de sock
    int fd;
	if(BIO_get_fd(bio, &fd) < 0){
            write(WRITE, "ERROR: crear le descriptor %s\n", DIM);
            // terminamos la ejecución del programa
            exit(-1);
	}
    FD_SET (fd, &desc);
    // Inicio del bit descriptor connList con el valor del descriptor de entrada estándar
    FD_SET (READ, &desc);

    while(1){
        // hacemos una copia de seguridad para asegurarnos de no perder los datos
        descCopy = desc;
        // ¿Hay algún socket listo para leer?
        PDEBUG("INFO: ¿Hay algún socket listo para leer?\n");
        error = select(fd + 1, &descCopy, NULL, NULL, NULL);
        //Comprobamos si ha ocurrido un error al ponernos a escuchar
        if(error < 0){
            write(WRITE, "ERROR: al realizar la selección {{select()}}: %s\n", DIM);
            // terminamos la ejecución del programa
            exit(-1);
        }

        // recorriendo los sockets para ver los que están activos
        PDEBUG("INFO: recorriendo los sockets para ver los que están activos\n");
        if(FD_ISSET(fd, &descCopy)){
            PDEBUG("INFO: Nuevo mensaje recibido\n");
            if(client_read(bio, &auxMsj, sizeof(sms)) <= 0){
                PDEBUG("INFO: El socket está cerrado\n");
                perror("Error al leer contenido del socket porque está cerrado\n");
                perror("El cliente se parará\n");
                exit(-1);
            }

            switch(auxMsj.flag){
                case OK: // mensaje de aceptacion, mismo comportamiento que msj
                case MSJ:  // mensaje recibido
                    if(serverTalk != 1 || strcmp(auxMsj.name, SERVER) == 0){
                        PDEBUG("INFO: Recibido mensaje\n");
                        sprintf(aux, "%s ~$> %s\n", auxMsj.name, auxMsj.text);
                        write(WRITE, aux, strlen(aux));
                        sync();
                    }
                    break;
                case SERV_EXIT: // el servidor se va a cerrar
                    PDEBUG("EXIT: El servidor se está cerrando, se dejará de leer\n");
                    shutdown(sock, SHUT_RDWR);
                    sprintf(aux, "%s ~$> Servidor desconectado\n", SERVER);
                    write(WRITE, aux, strlen(aux));
                    sprintf(aux, "El proceso cliente se cerrará\n");
                    write(WRITE, aux, strlen(aux));
                    exit(0);
                    break;
                default:
                    sprintf(aux, "Recibido un mensaje mal formado\n");
                    write(WRITE, aux, strlen(aux));
                    sync();
                    break;
            }
        }else if(FD_ISSET(READ, &descCopy)){
            PDEBUG("INFO: Nuevo mensaje escrito\n");

            bzero(&auxMsj.text, SMS_LEN); // inicializamos el array
            nbytes = read(READ, &auxMsj.text, SMS_LEN); // leemos de la entrada estándar
            auxMsj.text[nbytes - 1] = 0; // eliminamos el retorno de carro

            // nos salimos?
            if(strcmp(auxMsj.text, "-x") == 0 && serverTalk != 1){

                PDEBUG("EXIT: Cerrando el cliente, avisando al servidor...\n");
                auxMsj.flag = CLI_EXIT;

            }else if(strcmp(auxMsj.text, "--serv") == 0){ // queremos hablar con el servidor

                PDEBUG("SERV_ADMIN: Iniciando la comunicación directa con el servidor\n");
                sprintf(aux, "%s ~$> Iniciada conversación con el servidor\n", SERVER);
                write(WRITE, aux, strlen(aux));
                serverTalk = 1;
                continue;

            }else if(sscanf(auxMsj.text, "--mp %s", aux) == 1){ // queremos hablar con el servidor

                PDEBUG("MP: Mensaje privado detectado\n");
                strcpy(auxMsj.to, aux);
                sprintf(aux, "%s ~$> Inserte el mensaje privado\n", SERVER);
                write(WRITE, aux, strlen(aux));
                auxMsj.flag = MP;
                nbytes = read(READ, &auxMsj.text, SMS_LEN); // leemos de la entrada estándar
                auxMsj.text[nbytes - 1] = 0; // eliminamos el retorno de carro

            }else{ // es un mensaje

                if(serverTalk == 1){

                    PDEBUG("SERV_ADMIN: Enviando mensaje al servidor\n");
                    auxMsj.flag = SERV_ADMIN;

                    if(strcmp(auxMsj.text, "exit") == 0){

                        serverTalk = 0;
                        sprintf(aux, "%s ~$> Envio de mensajes de configuración terminada:\n", SERVER);
                        write(WRITE, aux, strlen(aux));
                        continue;

                    }

                }else{

                    auxMsj.flag = MSJ;

                }
            }

            strcpy(auxMsj.name, name); // hacemos una copia del nombre introducido para no perderlo
            PDEBUG("INFO: Enviando mensaje...\n");
            client_write(bio, &auxMsj, sizeof(sms));
            PDEBUG("INFO: Mensaje Enviado\n");

            // nos salimos?
            if(auxMsj.flag == CLI_EXIT){

                PDEBUG("EXIT: Cerrando el socket\n");
                shutdown(sock, SHUT_RDWR);
                PDEBUG("EXIT: Cerrando el cliente\n");
                exit(0);
                
            }
        }
    }
    
    return 0;
}
Example #18
0
RADCLIENT_LIST *client_list_parse_section(CONF_SECTION *section, UNUSED bool tls_required)
#endif
{
	bool		global = false, in_server = false;
	CONF_SECTION	*cs;
	RADCLIENT	*c;
	RADCLIENT_LIST	*clients;

	/*
	 *	Be forgiving.  If there's already a clients, return
	 *	it.  Otherwise create a new one.
	 */
	clients = cf_data_find(section, "clients");
	if (clients) return clients;

	clients = client_list_init(section);
	if (!clients) return NULL;

	if (cf_top_section(section) == section) global = true;

	if (strcmp("server", cf_section_name1(section)) == 0) in_server = true;

	/*
	 *	Associate the clients structure with the section.
	 */
	if (cf_data_add(section, "clients", clients, NULL) < 0) {
		cf_log_err_cs(section,
			   "Failed to associate clients with section %s",
		       cf_section_name1(section));
		client_list_free(clients);
		return NULL;
	}

	for (cs = cf_subsection_find_next(section, NULL, "client");
	     cs != NULL;
	     cs = cf_subsection_find_next(section, cs, "client")) {
		c = client_afrom_cs(cs, cs, in_server, false);
		if (!c) {
			return NULL;
		}

#ifdef WITH_TLS
		/*
		 *	TLS clients CANNOT use non-TLS listeners.
		 *	non-TLS clients CANNOT use TLS listeners.
		 */
		if (tls_required != c->tls_required) {
			cf_log_err_cs(cs, "Client does not have the same TLS configuration as the listener");
			client_free(c);
			client_list_free(clients);
			return NULL;
		}
#endif

		/*
		 *	FIXME: Add the client as data via cf_data_add,
		 *	for migration issues.
		 */

#ifdef WITH_DYNAMIC_CLIENTS
#ifdef HAVE_DIRENT_H
		if (c->client_server) {
			char const *value;
			CONF_PAIR *cp;
			DIR		*dir;
			struct dirent	*dp;
			struct stat stat_buf;
			char buf2[2048];

			/*
			 *	Find the directory where individual
			 *	client definitions are stored.
			 */
			cp = cf_pair_find(cs, "directory");
			if (!cp) goto add_client;

			value = cf_pair_value(cp);
			if (!value) {
				cf_log_err_cs(cs,
					   "The \"directory\" entry must not be empty");
				client_free(c);
				return NULL;
			}

			DEBUG("including dynamic clients in %s", value);

			dir = opendir(value);
			if (!dir) {
				cf_log_err_cs(cs, "Error reading directory %s: %s", value, fr_syserror(errno));
				client_free(c);
				return NULL;
			}

			/*
			 *	Read the directory, ignoring "." files.
			 */
			while ((dp = readdir(dir)) != NULL) {
				char const *p;
				RADCLIENT *dc;

				if (dp->d_name[0] == '.') continue;

				/*
				 *	Check for valid characters
				 */
				for (p = dp->d_name; *p != '\0'; p++) {
					if (isalpha((int)*p) ||
					    isdigit((int)*p) ||
					    (*p == ':') ||
					    (*p == '.')) continue;
						break;
				}
				if (*p != '\0') continue;

				snprintf(buf2, sizeof(buf2), "%s/%s",
					 value, dp->d_name);

				if ((stat(buf2, &stat_buf) != 0) ||
				    S_ISDIR(stat_buf.st_mode)) continue;

				dc = client_read(buf2, in_server, true);
				if (!dc) {
					cf_log_err_cs(cs,
						   "Failed reading client file \"%s\"", buf2);
					client_free(c);
					closedir(dir);
					return NULL;
				}

				/*
				 *	Validate, and add to the list.
				 */
				if (!client_add_dynamic(clients, c, dc)) {

					client_free(c);
					closedir(dir);
					return NULL;
				}
			} /* loop over the directory */
			closedir(dir);
		}
#endif /* HAVE_DIRENT_H */

	add_client:
#endif /* WITH_DYNAMIC_CLIENTS */
		if (!client_add(clients, c)) {
			cf_log_err_cs(cs,
				   "Failed to add client %s",
				   cf_section_name2(cs));
			client_free(c);
			return NULL;
		}

	}

	/*
	 *	Replace the global list of clients with the new one.
	 *	The old one is still referenced from the original
	 *	configuration, and will be freed when that is freed.
	 */
	if (global) {
		root_clients = clients;
	}

	return clients;
}
Example #19
0
/*
// Name: main
// In: argv, the arguments sent to the program.
//	   argc, the number of arguments sent to the program.
*/
int main (int argc, char **argv) {
	char port[6];
	char ssl_port[6];
	if(!arguments(argv, argc, port, ssl_port)) {
		printf("Usage: chat_server [port] [ssl port]\n");
		return 0;
	}
	char topic[MAXTOKENSIZE];
	memset(topic, '\0', MAXTOKENSIZE);
	// Set the signal handler.
	signal(SIGINT, signal_handler);
	server_socket = -1;
	ssl_socket = -1;
	server_socket_fd;
	int epoll_fd;
	struct epoll_event event, ssl_event;
	BIO *sbio;
	SSL *ssl;
	// Initialize ssl context.
	ctx=init_ctx();
	memset(&event, 0, sizeof event);
	memset(&ssl_event, 0, sizeof event);
	printf("Trying to create socket.\n");
	server_socket_fd = create_socket("telnet", port);
	ssl_socket_fd = create_socket("telnet", ssl_port);
	printf("Created socket.\n");
	// Check if sockets couldn't be created.
	if(server_socket_fd<0 || ssl_socket_fd<0) {
		fprintf(stderr, "Socket could not be created!\n");
		return -1;
	}
	// Set the socket to be non-blocking.
	server_socket = unblock_socket(server_socket_fd);
	ssl_socket = unblock_socket(ssl_socket_fd);
	if(server_socket<0 || ssl_socket<0) {
		fprintf(stderr, "Could not make socket non blocking.\n");
		return -1;
	}
	printf("Listening...\n");
	// Listen for incoming connections.
	server_socket = listen(server_socket_fd, NUMBER_PENDING_CONNECTIONS);
	ssl_socket = listen(ssl_socket_fd, NUMBER_PENDING_CONNECTIONS);
	if(server_socket < 0 || ssl_socket<0) {
		fprintf(stderr, "Could not listen to incoming connections.\n");
		return -1;
	}
	epoll_fd = epoll_create1(0);
	event.data.fd = server_socket_fd;
	// Run as edge-triggered, meaning that epoll_wait will return only on
	// new events.
	event.events = EPOLLIN | EPOLLET;
	// Create epoll control interface for the unsecure socket.
	server_socket = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, 
								server_socket_fd, &event);
	ssl_event.data.fd=ssl_socket_fd;
	ssl_event.events = EPOLLIN | EPOLLET;
	// Create epoll control interface for the secure socket.
	ssl_socket = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, ssl_socket_fd, &ssl_event);
	if(server_socket<0 || ssl_socket<0) {
		fprintf(stderr, "Could not create control interface for polling.\n");
		return -1;
	}
	events = calloc(MAXEVENTS, sizeof event);
	// Create hash map for storing connected clients.
	clients = hash_empty(MAXCLIENTS);
	struct sockaddr client_addr;
	socklen_t client_len;
	int insocket_fd;
	int client_socket;
	char host[MAXHOST_LEN], serv[MAXSERV_LEN];
	client_len = sizeof client_addr;
	// Main loop listening from events generated by epoll.
	while(1) {
		int n,i;
		// Wait for new events.
		n = epoll_wait(epoll_fd, events, MAXEVENTS, -1);
		for(i=0;i<n;i++) {
			if((events[i].events & EPOLLERR) || 
				events[i].events & EPOLLHUP || 
				(!(events[i].events & EPOLLIN))) {
				fprintf(stderr, "An error occured at an event.\n");
				clientconn_t *c;
				// If the an error-event occured at a connected client.
				if((c = hash_get(events[i].data.fd, clients))!=NULL) {
					client_close(c);
					hash_remove(c, clients);
				}
				close(events[i].data.fd);
				continue;
			}
			// If an a connection is made on the unsecure socket.
			else if(server_socket_fd == events[i].data.fd) {
				while(1) {
					// Accept connection.
					insocket_fd = accept(server_socket_fd, 
									&client_addr, &client_len);
					if(insocket_fd<0) {
						if(!(errno == EAGAIN || errno == EWOULDBLOCK)) {
							fprintf(stderr, "Could not accept "
											"input connection");
							break;
						} else {
							// If the whole handshake could not be made, 
							// keep trying to accept.
							break;
						}
					}
					// The address information.
					server_socket = getnameinfo(&client_addr, client_len, host,
							sizeof host, serv, sizeof serv, 
							NI_NUMERICHOST|NI_NUMERICSERV);
					if(server_socket==0) {
						printf("Connection accepted!\n");
					}
					// Make client socket non-blocking.
					server_socket = unblock_socket(insocket_fd);
					if(server_socket <0) {
						fprintf(stderr, "Could not make client socket "
								"non-blocking\n");
						return -1;
					}
					// Create an epoll interface for the client socket.
					event.data.fd = insocket_fd;
					event.events = EPOLLIN|EPOLLET;
					server_socket = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, 
									insocket_fd, &event);
					if(server_socket<0) {
						fprintf(stderr, "Could not create epoll "
										"interface for client\n");
						return -1;
					}
					printf("Added client(%d)!\n", insocket_fd);
					// Store client in the hash map.
					c = create_client(insocket_fd, &client_addr);
					hash_insert(c, clients);
				}
				continue;
			}
			// If a connection is made on the secure socket.
			else if(ssl_socket_fd == events[i].data.fd) {
				printf("Someone connected through ssl!\n");
				while(1) {
					// Accept in the same way as the unsecure socket.
					insocket_fd = accept(ssl_socket_fd, 
										&client_addr, &client_len);
					if(insocket_fd<0) {
						if(!(errno == EAGAIN || errno == EWOULDBLOCK)) {
							fprintf(stderr, "Could not accept input "
											"connection\n");
							break;
						} else {
							break;
						}
					}
					ssl_socket = getnameinfo(&client_addr, client_len, host, 
							sizeof host, serv, sizeof serv, 
							NI_NUMERICHOST|NI_NUMERICSERV);
					if(ssl_socket==0) {
						printf("Connection accepted!\n");
					}
					// Make socket non-blocking
					ssl_socket = unblock_socket(insocket_fd);
					if(ssl_socket<0){
						fprintf(stderr, "Could not make secure client "
										"socket non-blocking.\n");
						return -1;
					}
					// Create epoll interface for the secure client connection
					ssl_event.data.fd = insocket_fd;
					ssl_event.events = EPOLLIN;
					ssl_socket = epoll_ctl(epoll_fd, EPOLL_CTL_ADD,
											insocket_fd, &ssl_event);
					if(ssl_socket<0) {
						fprintf(stderr, "Could not create "
										"epoll interface for client.\n");
						return -1;
					}
					printf("Added client!(%d)\n", insocket_fd);
					c = create_client(insocket_fd, &client_addr);
					// Set up ssl.
					c->ssl_status=STATUS_HANDSHAKE;
					c->ssl = SSL_new(ctx);
					SSL_set_fd(c->ssl, insocket_fd);
					SSL_set_mode(c->ssl, SSL_MODE_ENABLE_PARTIAL_WRITE);
					hash_insert(c, clients);
				}
				continue;
			}
			// If an incoming message has caused an event.
			else {
				int done = 0;
				while (1) {
					ssize_t count;
					char buf[MAXBUFSIZE];
					memset(buf, '\0', MAXBUFSIZE);
					clientconn_t *c = hash_get(events[i].data.fd, clients);
					// If the client is trying to make an ssl handshake.
					if(c->ssl_status==STATUS_HANDSHAKE) {
						int r=1;
						r=SSL_accept(c->ssl);
						if (r<0) {
							if(SSL_get_error(c->ssl, r)!=SSL_ERROR_WANT_READ &&
							  SSL_get_error(c->ssl, r)!=SSL_ERROR_WANT_WRITE ){
									done=1;
									printf("Could not accept ssl "
											"connection\n");
								break;
							}
						} else {
							// Handshake is done.
							c->ssl_status=STATUS_ACCEPTED;
						}
					}
					else {
						// Read data from client.
						int count = client_read(c, buf, sizeof buf);
						if(count<0) {
							if(errno!=EAGAIN) {
								fprintf(stderr, "Could not read"
											" from socket!\n");
								done=1;
							}
							break;
						}
						if(buf[MAXBUFSIZE-1] != '\0') {
							write(events[i].data.fd, "* BAD Buffer will "
													"overflow\r\n", 28);
							break;
						}
						else if (count==0) {
							done=1;
							break;
						}
						if (handle_input(events[i].data.fd, 
								buf, count, clients, topic)==CLIENTCLOSED) {
							done=1;
							break;
						}
						if(server_socket<0) {
							fprintf(stderr, "Could get input.\n");
							return -1;
						}
					}
				}
				// Client connection is done, wants to disconnect.
				if(done) {
					printf("Closed connection!\n");
					clientconn_t *closeclient = hash_get(events[i].data.fd, 
															clients);
					if(closeclient != NULL) {
						hash_remove(closeclient, clients);
						client_close(closeclient);
					}
					close(events[i].data.fd);
				}
			}
		}
	}
	free(events);
	close(server_socket_fd);
	return 0;
}
Example #20
0
/*
 * Replicates a given file
 * Takes the index in the server table for from and to
 * Caller must lock the global tables (modifies the file_list)
 */
int replicate(int f_idx, int from, int to)
{
  char *f_name = file_list[f_idx].name;
  char *s_from = server_list[from].name;
  char *s_to = server_list[to].name;
  int fd_from = -1;
  int fd_to = -1;
  int sock_from = -1;
  int sock_to = -1;
  int r_len = -1, w_len = -1;
  char buff[8192];

  // See if src is same as destn
  if (from == to) {
    printf ("***NO REPLICATE*** from == to\n");
    return(-1);;
  }
  // connect to servers
  if (((sock_from = connect_to_server(s_from, server_port)) < 0 ) ||
      ((sock_to = connect_to_server(s_to, server_port)) < 0 )) {
    perror("Replication failed");
    if (sock_from >= 0) close(sock_from);
    if (sock_to >= 0) close(sock_to);
    return(-1);
  }

  // open files
  if (((fd_from = client_open(sock_from, f_name, O_RDONLY)) < 0 ) ||
      ((fd_to = client_open(sock_to, f_name, O_CREAT | O_WRONLY)) < 0 )) {
    perror("Replication failed");
    if (fd_from >= 0) client_close(sock_from, fd_from);
    client_end(sock_from);
    if(fd_to >= 0) client_close(sock_to, fd_to);
    client_end(sock_to);
    return(-2);
  }

  // read file from source server and transfer to dest server
  do {
    if ((r_len = client_read(sock_from, fd_from, buff,
			     sizeof(buff))) < 0) {
      perror("Replication failed");
      client_close(sock_from, fd_from);
      client_end(sock_from);
      client_close(sock_to, fd_to);
      client_end(sock_to);
      return(-3);
    }

    if ((w_len = client_write(sock_to, fd_to, buff,
			      r_len)) < 0 ) {
      perror("Replication failed");
      client_close(sock_from, fd_from);
      client_end(sock_from);
      client_close(sock_to, fd_to);
      client_end(sock_to);
      return(-4);
    }
  } while (r_len == sizeof(buff));    // read until eof

  // close files
  client_close(sock_from, fd_from);
  client_end(sock_from);
  client_close(sock_to, fd_to);
  client_end(sock_to);

  // update tables - add destn server to file's record
  file_list[f_idx].index[file_list[f_idx].tot_idx++] = to;

  return(0);

}
Example #21
0
int main(int argc, char **argv)
{
  int status, i, listener;
  time_t tardy;
  char *port, *p;
  extern char *database;
  struct stat stbuf;
  struct utsname uts;
  fd_set readfds, writefds, xreadfds, xwritefds;
  int nfds, counter = 0;

  whoami = argv[0];
  /*
   * Error handler init.
   */
  mr_init();
  set_com_err_hook(mr_com_err);
  setvbuf(stderr, NULL, _IOLBF, BUFSIZ);

  port = strchr(MOIRA_SERVER, ':') + 1;

  for (i = 1; i < argc; i++)
    {
      if (!strcmp(argv[i], "-db") && i + 1 < argc)
	{
	  database = argv[i + 1];
	  i++;
	}
      else if (!strcmp(argv[i], "-p") && i + 1 < argc)
	{
	  port = argv[i + 1];
	  i++;
	}
      else
	{
	  com_err(whoami, 0, "Usage: moirad [-db database][-p port]");
	  exit(1);
	}
    }

  status = krb5_init_context(&context);
  if (status)
    {
      com_err(whoami, status, "Initializing krb5 context.");
      exit(1);
    }

  status = krb5_get_default_realm(context, &krb_realm);
  if (status)
    {
      com_err(whoami, status, "Getting default Kerberos realm.");
      exit(1);
    }

  /*
   * Database initialization.  Only init if database should be open.
   */

  if (stat(MOIRA_MOTD_FILE, &stbuf) != 0)
    {
      if ((status = mr_open_database()))
	{
	  com_err(whoami, status, "trying to open database.");
	  exit(1);
	}
      sanity_check_database();
    }
  else
    {
      dormant = ASLEEP;
      com_err(whoami, 0, "sleeping, not opening database");
    }

  sanity_check_queries();

  /*
   * Get moira server hostname for authentication
   */
  if (uname(&uts) < 0)
    {
      com_err(whoami, errno, "Unable to get local hostname");
      exit(1);
    }
  host = canonicalize_hostname(xstrdup(uts.nodename));
  for (p = host; *p && *p != '.'; p++)
    {
      if (isupper(*p))
	*p = tolower(*p);
    }
  *p = '\0';

  /*
   * Set up client array handler.
   */
  nclients = 0;
  clientssize = 10;
  clients = xmalloc(clientssize * sizeof(client *));

  mr_setup_signals();

  journal = fopen(JOURNAL, "a");
  if (!journal)
    {
      com_err(whoami, errno, "opening journal file");
      exit(1);
    }

  /*
   * Establish template connection.
   */
  listener = mr_listen(port);
  if (listener == -1)
    {
      com_err(whoami, MR_ABORTED, "trying to create listening connection");
      exit(1);
    }
  FD_ZERO(&xreadfds);
  FD_ZERO(&xwritefds);
  FD_SET(listener, &xreadfds);
  nfds = listener + 1;

  com_err(whoami, 0, "started (pid %d)", getpid());
  com_err(whoami, 0, rcsid);
  if (dormant != ASLEEP)
    send_zgram("MOIRA", "server started");
  else
    send_zgram("MOIRA", "server started, but database closed");

  /*
   * Run until shut down.
   */
  while (!takedown)
    {
      int i;
      struct timeval timeout = {60, 0}; /* 1 minute */

      /* If we're supposed to go down and we can, do it */
      if (((dormant == AWAKE) && (nclients == 0) &&
	   (stat(MOIRA_MOTD_FILE, &stbuf) == 0)) ||
	  (dormant == SLEEPY))
	{
	  mr_close_database();
	  com_err(whoami, 0, "database closed");
	  mr_setup_signals();
	  send_zgram("MOIRA", "database closed");
	  dormant = ASLEEP;
	}

      /* Block until something happens. */
      memcpy(&readfds, &xreadfds, sizeof(readfds));
      memcpy(&writefds, &xwritefds, sizeof(writefds));
      if (select(nfds, &readfds, &writefds, NULL, &timeout) == -1)
	{
	  if (errno != EINTR)
	    com_err(whoami, errno, "in select");
	  continue;
	}

      if (takedown)
	break;

      if (child_exited_abnormally)
	{
	  critical_alert(whoami, "moirad", "%d: child exits with signal %d status %d",
			 child_pid, child_signal, child_status);
	  child_exited_abnormally = 0;
	}

      time(&now);
      tardy = now - 30 * 60;

      /* If we're asleep and we should wake up, do it */
      if ((dormant == ASLEEP) && (stat(MOIRA_MOTD_FILE, &stbuf) == -1) &&
	  (errno == ENOENT))
	{
	  mr_open_database();
	  com_err(whoami, 0, "database open");
	  mr_setup_signals();
	  send_zgram("MOIRA", "database open again");
	  dormant = AWAKE;
	}

      /* Handle any new connections */
      if (FD_ISSET(listener, &readfds))
	{
	  int newconn, addrlen = sizeof(struct sockaddr_in);
	  struct sockaddr_in addr;
	  client *cp;

	  newconn = accept(listener, (struct sockaddr *)&addr, &addrlen);
	  if (newconn == -1)
	    com_err(whoami, errno, "accepting new connection");
	  else if (newconn > 0)
	    {
	      if (newconn + 1 > nfds)
		nfds = newconn + 1;
	      FD_SET(newconn, &xreadfds);

	      /* Add a new client to the array */
	      nclients++;
	      if (nclients > clientssize)
		{
		  clientssize = 2 * clientssize;
		  clients = xrealloc(clients, clientssize * sizeof(client *));
		}

	      clients[nclients - 1] = cp = xmalloc(sizeof(client));
	      memset(cp, 0, sizeof(client));
	      cp->con = newconn;
	      cp->id = counter++;
	      cp->last_time_used = now;
	      cp->haddr = addr;
	      cp->tuplessize = 1;
	      cp->tuples = xmalloc(sizeof(mr_params));
	      memset(cp->tuples, 0, sizeof(mr_params));
	      cp->state = CL_ACCEPTING;
	      cp->version = 2;

	      cur_client = cp;
	      com_err(whoami, 0,
		      "New connection from %s port %d (now %d client%s)",
		      inet_ntoa(cp->haddr.sin_addr),
		      (int)ntohs(cp->haddr.sin_port),
		      nclients, nclients != 1 ? "s" : "");
	    }
	}

      /* Handle any existing connections. */
      for (i = 0; i < nclients; i++)
	{
	  cur_client = clients[i];

	  if (FD_ISSET(clients[i]->con, &writefds))
	    {
	      client_write(clients[i]);
	      if (!clients[i]->ntuples)
		{
		  FD_CLR(clients[i]->con, &xwritefds);
		  FD_SET(clients[i]->con, &xreadfds);
		}
	      clients[i]->last_time_used = now;
	    }

	  if (FD_ISSET(clients[i]->con, &readfds))
	    {
	      if (clients[i]->state == CL_ACCEPTING)
		{
		  switch(mr_cont_accept(clients[i]->con,
					&clients[i]->hsbuf,
					&clients[i]->hslen))
		    {
		    case -1:
		      break;

		    case 0:
		      clients[i]->state = CL_CLOSING;
		      break;

		    default:
		      clients[i]->state = CL_ACTIVE;
		      clients[i]->hsbuf = NULL;
		      break;
		    }
		}
	      else
		{
		  client_read(clients[i]);
		  if (clients[i]->ntuples)
		    {
		      FD_CLR(clients[i]->con, &xreadfds);
		      FD_SET(clients[i]->con, &xwritefds);
		    }
		  clients[i]->last_time_used = now;
		}
	    }

	  if (clients[i]->last_time_used < tardy)
	    {
	      com_err(whoami, 0, "Shutting down connection due to inactivity");
	      clients[i]->state = CL_CLOSING;
	    }

	  if (clients[i]->state == CL_CLOSING)
	    {
	      client *old;

	      com_err(whoami, 0, "Closed connection (now %d client%s, "
		      "%d queries)", nclients - 1, nclients != 2 ? "s" : "",
		      newqueries);

	      shutdown(clients[i]->con, 2);
	      close(clients[i]->con);
	      FD_CLR(clients[i]->con, &xreadfds);
	      FD_CLR(clients[i]->con, &xwritefds);
	      free_rtn_tuples(clients[i]);
	      free(clients[i]->tuples);
	      if (clients[i]->hsbuf)
		free(clients[i]->hsbuf);
	      old = clients[i];
	      clients[i] = clients[--nclients];
	      free(old);
	    }

	  cur_client = NULL;
	  if (takedown)
	    break;
	}
    }

  com_err(whoami, 0, "%s", takedown);
  if (dormant != ASLEEP)
    mr_close_database();
  send_zgram("MOIRA", takedown);
  return 0;
}
Example #22
0
static void *st_poolThread(void* pArg)
{
	char buf[BUFFER_SIZE];
	cJSON *msg = NULL;

	pthread_cleanup_push(st_poolThreadCleanup, NULL);
	for(;;)
	{
		pthread_testcancel();

		if (client_read( &pool.socket, buf, sizeof(buf)) <= 0)
		{
			usleep(50000);
			continue;
		}

		RPC_TRACE("st: <- %s\n", buf);
		msg = cJSON_Parse( buf );
		if( !msg )
		{
			eprintf("%s: failed to parse message: '%s'\n", __FUNCTION__, buf);
			continue;
		}

		elcdRpcType_t type = elcdRpcInvalid;
		cJSON *value = NULL;
		cJSON *id = cJSON_GetObjectItem(msg, "id");
		if( !id || id->type != cJSON_Number || id->valueint == 0 )
		{
			eprintf("%s: missing id\n", __FUNCTION__);
			goto type_known;
		}
		value = cJSON_GetObjectItem( msg, "method" );
		if( value != NULL && value->type == cJSON_String )
		{
			type = elcdRpcRequest;
			goto type_known;
		}
		value = cJSON_DetachItemFromObject( msg, "result" );
		if( value != NULL && value->type != cJSON_NULL )
		{
			type = elcdRpcResult;
			goto type_known;
		}
		value = cJSON_DetachItemFromObject( msg, "error" );
		if( value != NULL && value->type != cJSON_NULL )
		{
			type = elcdRpcError;
		}
type_known:
		dprintf( "%s:   <- %s type %d\n", __FUNCTION__, buf, type);
		switch( type )
		{
			case elcdRpcInvalid:
				eprintf("%s: malformed message: '%s'\n", __FUNCTION__, buf);
				break;
			case elcdRpcRequest:
				/// TODO
				eprintf("%s: don't know what to do with request %s\n", __FUNCTION__, value->valuestring);
				break;
			case elcdRpcError:
			case elcdRpcResult:
			{
				int i;
				for( i = 0; i < RPC_POOL_SIZE; i++ )
					if( (unsigned int)id->valueint == pool.waiting[i].id )
					{
                        if(pool.waiting[i].callback)
                        {
                            pool.waiting[i].callback( type, value, pool.waiting[i].pArg );
                        }
						st_poolFreeAt(i);
						break;
					}
				if( i >= RPC_POOL_SIZE )
				{
					eprintf("%s: lost message %6u\n", __FUNCTION__, (unsigned int)id->valueint);
					cJSON_Delete(value);
				}
				st_poolPrint();
				break;
			}
		}

		cJSON_Delete(msg);
		msg = NULL;
	}
	pthread_cleanup_pop(1);

	pthread_exit(NULL);
}
Example #23
0
// handle the websocket handshake
void client_read_ws_handshake ( struct bufferevent* be, void* arg ) {
  // Examine the input buffer without reading from it.
  // Wait untill we have the full handshake to begin processing.
  int len = EVBUFFER_LENGTH ( EVBUFFER_INPUT ( be ) );
  char* data = EVBUFFER_DATA (  EVBUFFER_INPUT ( be ) );
  char buf[1024];
  if ( len > sizeof buf ) len = sizeof buf;
  memcpy ( buf, data, len );
  buf[len] = '\0';

  // the spec http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-68 is very
  // strict regarding the handshake.
  
  char* endofheaders = strstr ( buf, "\r\n\r\n" );
  if ( endofheaders == NULL ) return;

  char* origin;
  char* eoo; // end of origin
  if ( ( origin = strstr ( buf, "Origin:" ) ) == NULL || 
       ( eoo = strchr ( origin, '\r' ) ) == NULL ) {
    // didn't get all of the websocket headers, read more
    return;
  }

  origin += 8;
  *eoo = '\0';
  // chop the buffer up at each space char
  char* strings[50];
  int n = 0;
  char* ptmp;
  char* p = strtok_r ( buf, " ", &ptmp );
  while ( n < 50 && p != NULL ) {
    strings[n++] = p;
    p = strtok_r ( NULL, " ", &ptmp );
  }
  if ( n < 7 || strncmp ( "GET", strings[0], 3 ) != 0 ||
       strncmp ( "HTTP/1.1\r\nUpgrade:", strings[2], 18 ) != 0 ||
       strncmp ( "WebSocket\r\nConnection:", strings[3], 22 ) != 0 ||
       strncmp ( "Upgrade\r\nHost:", strings[4], 15 ) != 0 ||
       strlen ( strings[5] ) < 9 ||
       strlen ( strings[6] ) < 4 ) {
    // error
  }
  
  char* host = strings[5];
  int l = strlen ( host );
  host[l - 9] = '\0';

  // grab the info we are interested in
  host = strdup ( host );  origin = strdup ( origin ); char* uri = strdup ( strings[1] );

  // remove the handshake and headers from the input buffer
  int hs_len = buf - endofheaders + 4;
  bufferevent_read ( be, buf, hs_len );

  // send handshake response
  snprintf ( buf, sizeof buf,
	     "HTTP/1.1 101 Web Socket Protocol Handshake\r\n"
	     "Upgrade: WebSocket\r\n"
	     "Connection: Upgrade\r\n"
	     "WebSocket-Origin: %s\r\n"
	     "WebSocket-Location: ws://%s%s\r\n\r\n",
	     origin, host, uri );
  free ( host ); free ( origin ); free ( uri );
  
  // send websock handshake
  bufferevent_write ( be, buf, strlen ( buf ) );
  bufferevent_enable ( be, EV_WRITE );
  
  struct bufferevent* server = connect_to_server ( serverhost, serverport, be );
  
  // reconfig the read callback 
  bufferevent_setcb ( be, client_read, NULL, be_error, server );
  client_read ( be, server );
}