Ejemplo n.º 1
0
static int add_client_resource(struct client *client,
			       struct client_resource *resource, gfp_t gfp_mask)
{
	unsigned long flags;
	int ret;

 retry:
	if (idr_pre_get(&client->resource_idr, gfp_mask) == 0)
		return -ENOMEM;

	spin_lock_irqsave(&client->lock, flags);
	if (client->in_shutdown)
		ret = -ECANCELED;
	else
		ret = idr_get_new(&client->resource_idr, resource,
				  &resource->handle);
	if (ret >= 0) {
		client_get(client);
		if (resource->release == release_iso_resource)
			schedule_iso_resource(container_of(resource,
						struct iso_resource, resource));
	}
	spin_unlock_irqrestore(&client->lock, flags);

	if (ret == -EAGAIN)
		goto retry;

	return ret < 0 ? ret : 0;
}
int main(int argc, char *argv[])
{
  int confd;
  struct sockaddr_in server_addr;

  if(argc < 5)
  {
    printf("input format is :\nput [-h hostname] [-p portname] local_filename remote_filename\nget [-h hostname] [-p portname] remote_filename local_filename\n");
    exit(1);
  }
  if(!strcmp(argv[1],"put"))//输出提示。
   printf("%s hostname:%s,portname:%s,local_filename:%s,remote_filename:%s\n",argv[1],argv[2],argv[3],argv[4],argv[5]);
 else
   printf("%s hostname:%s,portname:%s,local_filename:%s,remote_filename:%s\n",argv[1],argv[2],argv[3],argv[5],argv[4]);


  server_addr.sin_family = PF_INET;//PF_INET(协议族)
  server_addr.sin_addr.s_addr = inet_addr(argv[2]);//主机字节顺序转换成网络字节顺序
  server_addr.sin_port = htons(atoi(argv[3]));//该函数把一个用数字和点表示的IP地址的字符串转换成一个无符号长整型
  bzero(&server_addr.sin_zero,8);  //sin_zero是为了让sockaddr与sockaddr_in两个数据结构保持大小相同而保留的空字节
 
  if ((confd = socket(PF_INET, SOCK_STREAM, 0)) == -1)
  {
    perror("socket fail\n");
    exit(1);
  }


  if (connect(confd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1)
  {
    perror("connect fail");
    exit(1);
  }

  if (!strcmp(argv[1], "put"))
  {
   client_put(confd,argv[4],argv[5]);
  }
  else if (!strcmp(argv[1], "get"))
  {
   client_get(confd,argv[5],argv[4]);
  }
  else
  {
    printf("input format error\n");
  }

  close(confd);//关闭连接

  return 0;

}
Ejemplo n.º 3
0
static int init_request(struct client *client,
			struct fw_cdev_send_request *request,
			int destination_id, int speed)
{
	struct outbound_transaction_event *e;
	int ret;

	if (request->tcode != TCODE_STREAM_DATA &&
	    (request->length > 4096 || request->length > 512 << speed))
		return -EIO;

	e = kmalloc(sizeof(*e) + request->length, GFP_KERNEL);
	if (e == NULL)
		return -ENOMEM;

	e->client = client;
	e->response.length = request->length;
	e->response.closure = request->closure;

	if (request->data &&
	    copy_from_user(e->response.data,
			   u64_to_uptr(request->data), request->length)) {
		ret = -EFAULT;
		goto failed;
	}

	e->r.resource.release = release_transaction;
	ret = add_client_resource(client, &e->r.resource, GFP_KERNEL);
	if (ret < 0)
		goto failed;

	/* Get a reference for the transaction callback */
	client_get(client);

	fw_send_request(client->device->card, &e->r.transaction,
			request->tcode, destination_id, request->generation,
			speed, request->offset, e->response.data,
			request->length, complete_transaction, e);
	return 0;

 failed:
	kfree(e);

	return ret;
}
Ejemplo n.º 4
0
/**
 * @brief Displays shell and parses input from user.
 *
 * Only allows integer input.
 * Call a function based on user selection (1-6).
 * If connected to a server, it disconnects before exiting.
 * @param r A pointer to a record structure.
 * @return Returns 0 on success, -1 otherwise.
 */
int command_parser()
{
    
    printf("\n\n------------------------------------------\n"
           "\t1) Connect\n"
           "\t2) Authenticate\n"
           "\t3) Get\n"
           "\t4) Set\n"
           "\t5) Query\n"
           "\t6) Disconnect\n"
           "\t7) Exit\n"
           "------------------------------------------\n\n\n");
    
    int option, status;
    struct storage_record r;
    
    bool read_success = false;
    while(read_success == false)
    {
        printf("Please enter your selection: ");
        char *l = fgets(input_buffer, sizeof input_buffer, stdin);
        if(l != input_buffer || (sscanf(input_buffer, "%d %s", &option, trash) != 1) || option > 7 || option < 1)
            printf("Invalid selection. Please enter a valid option number (1-6).\n");
        else
            read_success = true;
    }
    
    switch (option)
    {
        case 1: // Connect to server
            status = client_connect();
            break;
            
        case 2: // Authenticate the client.
            status = client_auth();
            break;
            
        case 3: // Issue storage_get
            client_get(&r);
            n_gets++;
            break;
            
        case 4: // Issue storage_set
            client_set(&r);
            n_sets++;
            break;
            
        case 5: //Issue client_query
            client_query();
            break;
            
        case 6: // Disconnect from server
            status = client_disconnect();
            break;
            
        case 7: //Exit
            if (connected)
                status = client_disconnect();
            status = -1; // To stop main loop
            printf("Goodbye!\n");
            break;
            
        default:
            status = -1;
            printf("Invalid selection.\n");
            break;
    }
    
    return status;
}
Ejemplo n.º 5
0
int main (int argc, char **argv)
{
	int sock, len2, len;
	char opcode, filename[196], mode[12] = "octet"; // default is octet
	struct hostent *host;
	struct sockaddr_in server;
	char* host_addr = "127.0.0.1";
	FILE *fp;

	if (argc < 2)
	{
		printf("invalid format of command\n");
		printf("Command format: ./client -h [host_addr] -P [port] -g|-p [filename] [-n] \n");
		return 0;
	}

	argv++;
	argc--;

	if (strcmp(argv[0], "-h") == 0)
	{
		if (argc==1) 
		{
			printf("invalid format of command\n");
			printf("Command format: ./client -h [host_addr] -P [port] -g|-p [filename] [-n] \n");
			return 0;
		}
		host_addr = argv[1];
		argv+=2;
		argc-=2;
	}
	if (strcmp(argv[0], "-P")==0){
		if (argc==1) 
		{
			printf("invalid format of command\n");
			printf("Command format: ./client -h [host_addr] -P [port] -g|-p [filename] [-n] \n");
			return 0;
		}
		port = atoi(argv[1]);

		argv+=2;
		argc-=2;
	}
	if (strcmp(argv[0], "-g")==0){
		if (argc==1) 
		{
			printf("invalid format of command\n");
			printf("Command format: ./client -h [host_addr] -P [port] -g|-p [filename] [-n] \n");
			return 0;
		}
		strncpy (filename, argv[1], sizeof (filename) - 1);
		opcode = RRQ;
		argv+=2;
		argc-=2;
	} else if (strcmp(argv[0], "-p")==0){
		if (argc==1) 
		{
			printf("invalid format of command\n");
			printf("Command format: ./client -h [host_addr] -P [port] -g|-p [filename] [-n] \n");
			return 0;
		}
		strncpy (filename, argv[1], sizeof (filename) - 1);
		opcode = WRQ;
		argv+=2;
		argc-=2;
	} else if (strcmp(argv[0], "-n")==0){
		strncpy (mode, "netascii", sizeof (mode) - 1);
		printf ("Client: The mode is set to netascii\n");
	} else{
		printf("Command format: ./client -h [host_addr] -P [port] -g|-p [filename] [-n] \n");
		return (0);
	}

	printf("Client: server ip address: %s and port: %d \n", host_addr, port);
	if (!(host = gethostbyname (host_addr)))
	{
		perror ("could not obtain host address as");
		exit (2);
	}

	printf("Client: Opening file: %s in %s mode \n", filename, (opcode == WRQ ? "Read": "Write") );
	if(opcode == WRQ)
		fp = fopen (filename, "r");	
	else if(opcode == RRQ)
		fp = fopen (filename, "w");		
	if (fp == NULL)
	{
		printf ("Client: file could not be opened: file not found or permission denied\n");
		return 0;
	}
	fclose (fp);		


	/*Create the socket, a -1 will show us an error */
	if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
	{
		perror("Client: socket");
		return 0;
	}

	 // bind to an arbitrary return address 
	 // because this is the client side, we don't care about the 
	 // address since no application will connect here  
	 // INADDR_ANY is the IP address and 0 is the socket 
	 // htonl converts a long integer (e.g. address) to a network 
	 // representation (agreed-upon byte ordering 

	bzero(&server, sizeof (server));
	server.sin_family = AF_INET;
	memcpy (&server.sin_addr, host->h_addr, host->h_length);
	// server.sin_addr.s_addr = htonl (INADDR_ANY);
	server.sin_port = htons (port);	


	len2 = sizeof(server);
	memset(buf, 0, 512);
	// creates RRQ packet
	len = request_packet(opcode, filename, mode, buf);
	if (sendto (sock, buf, len, 0, (struct sockaddr *) &server, len2) != len)
	{
		perror("Client: sendto has returend an error");
		exit(-1);
	}
	printf("Client: %s packet sent\n", (opcode==1 ? "RRQ":"WRQ"));
	switch (opcode)
	{
		case RRQ:
			client_get(filename, server, mode, sock);
			break;
		case WRQ:
			client_put(filename, server, mode, sock);
			break;
		default:
			printf("Invalid opcode. Packet discarded.");
	}
	close(sock);
	return 1;
}
Ejemplo n.º 6
0
static void schedule_iso_resource(struct iso_resource *r)
{
	client_get(r->client);
	if (!schedule_delayed_work(&r->work, 0))
		client_put(r->client);
}
Ejemplo n.º 7
0
static void iso_resource_work(struct work_struct *work)
{
	struct iso_resource_event *e;
	struct iso_resource *r =
			container_of(work, struct iso_resource, work.work);
	struct client *client = r->client;
	int generation, channel, bandwidth, todo;
	bool skip, free, success;

	spin_lock_irq(&client->lock);
	generation = client->device->generation;
	todo = r->todo;
	/* Allow 1000ms grace period for other reallocations. */
	if (todo == ISO_RES_ALLOC &&
	    time_is_after_jiffies(client->device->card->reset_jiffies + HZ)) {
		if (schedule_delayed_work(&r->work, DIV_ROUND_UP(HZ, 3)))
			client_get(client);
		skip = true;
	} else {
		/* We could be called twice within the same generation. */
		skip = todo == ISO_RES_REALLOC &&
		       r->generation == generation;
	}
	free = todo == ISO_RES_DEALLOC ||
	       todo == ISO_RES_ALLOC_ONCE ||
	       todo == ISO_RES_DEALLOC_ONCE;
	r->generation = generation;
	spin_unlock_irq(&client->lock);

	if (skip)
		goto out;

	bandwidth = r->bandwidth;

	fw_iso_resource_manage(client->device->card, generation,
			r->channels, &channel, &bandwidth,
			todo == ISO_RES_ALLOC ||
			todo == ISO_RES_REALLOC ||
			todo == ISO_RES_ALLOC_ONCE,
			r->transaction_data);
	/*
	 * Is this generation outdated already?  As long as this resource sticks
	 * in the idr, it will be scheduled again for a newer generation or at
	 * shutdown.
	 */
	if (channel == -EAGAIN &&
	    (todo == ISO_RES_ALLOC || todo == ISO_RES_REALLOC))
		goto out;

	success = channel >= 0 || bandwidth > 0;

	spin_lock_irq(&client->lock);
	/*
	 * Transit from allocation to reallocation, except if the client
	 * requested deallocation in the meantime.
	 */
	if (r->todo == ISO_RES_ALLOC)
		r->todo = ISO_RES_REALLOC;
	/*
	 * Allocation or reallocation failure?  Pull this resource out of the
	 * idr and prepare for deletion, unless the client is shutting down.
	 */
	if (r->todo == ISO_RES_REALLOC && !success &&
	    !client->in_shutdown &&
	    idr_find(&client->resource_idr, r->resource.handle)) {
		idr_remove(&client->resource_idr, r->resource.handle);
		client_put(client);
		free = true;
	}
	spin_unlock_irq(&client->lock);

	if (todo == ISO_RES_ALLOC && channel >= 0)
		r->channels = 1ULL << channel;

	if (todo == ISO_RES_REALLOC && success)
		goto out;

	if (todo == ISO_RES_ALLOC || todo == ISO_RES_ALLOC_ONCE) {
		e = r->e_alloc;
		r->e_alloc = NULL;
	} else {
		e = r->e_dealloc;
		r->e_dealloc = NULL;
	}
	e->resource.handle	= r->resource.handle;
	e->resource.channel	= channel;
	e->resource.bandwidth	= bandwidth;

	queue_event(client, &e->event,
		    &e->resource, sizeof(e->resource), NULL, 0);

	if (free) {
		cancel_delayed_work(&r->work);
		kfree(r->e_alloc);
		kfree(r->e_dealloc);
		kfree(r);
	}
 out:
	client_put(client);
}
Ejemplo n.º 8
0
/*
 * Maneja los requests que hacen los clientes.
 */
int
connection_client_handler(events_t *ev, event_t *event)
{
	client_t *client = client_get(event->fd);

	char *data =
	"ICY 200 OK\r\n"
	"icy-notice1: NOTICE 1\r\n"
	"icy-notice2: NOTICE 2\r\n"
	"icy-name: STATION NAME\r\n"
	"icy-genre: GENRE\r\n"
	"icy-url: http://localhost\r\n"
	"content-type: audio/mpeg\r\n"
	"icy-pub: 1\r\n"
	"icy-metaint: 0\r\n"
	"icy-br: 128\r\n"
	"\r\n";

	// TODO a buffer moverlo de aca, no tiene sentido alocarlo en la stack cada ves
	// que llamamos al event handler
	char buffer[512];

	if(event->event_mask & EVENT_READ)
	{
		// Evento de lectura, puede ser que se cerro el cliente
		// o que es el inicio de la conexion y estamos por
		// intercambiar headers.
		// Otra cosa es error, no esperada.

		// Esta funcion es llamada cada ves que hay un evento de lectura
		// es decir cuando uno de nuestros clientes nos envia algo.
		// Esto solo sucede al inicio de la conexion cuando el servidor y
		// el cliente intercambian headers con informacion sobre la proxima
		// conexion.
		//
		// Vamos a aceptar los clientes nuevos aca, a nivel ICECAST no nivel socket
		// es decir que vamos a crear las estructuras necesarias para
		// mantener la informacion sobre los clientes.
		// Tambien vamos a manejar las desconexiones. Estas las vamos a detectar
		// por que el socket al leer nos va a devolver 0 bytes.


		// Si el cliente estaba en estado WAITING lo proximo que tendria
		// que enviar son headers de ICECAST para establecer conexion.
		if(client->state == CLIENT_WAITING)
		{
			#ifdef DEBUG
			printf("[cliente=%d] connection_client_handler(EVENT_READ):CLIENT_WAITING\n", event->fd);
			#endif

			if(socket_read_string(event->fd, buffer, sizeof(buffer)) == -1)
			{
				perror("connection_client_handler():");
				return -1;
			}

			// Por ahora la verificacion es simple
			if(strcasestr(buffer, "icy-metadata: 1") == NULL)
			{
				#ifdef DEBUG
				fprintf(stderr, "[cliente=%d] Headers invalidos, desconectando\n", event->fd);
				#endif

				event_del(ev, event->fd);
				socket_close(event->fd);
				client_destroy(client);
				server.clients--;

				return 0;
			}

			// Si esta todo bien seteamos como empezando la conexion
			client->state = CLIENT_STARTING;

			return 0;
		}
		else
		{
			// Manejar desconecciones
			if(socket_read_string(event->fd, buffer, sizeof(buffer)) == 0)
			{
				#ifdef DEBUG
				fprintf(stderr, "[cliente=%d] Desconectando cliente\n", event->fd);
				#endif

				event_del(ev, event->fd);
				socket_close(event->fd);
				client_destroy(client);
				server.clients--;

				return 0;
			}

			#ifdef DEBUG
			fprintf(stderr, "[cliente=%d] Invalid read\n%s\n", event->fd, buffer);
			#endif
		}
	}
	else if(event->event_mask & EVENT_WRITE)
	{
		char *buffer;
		int ret;

		switch(client->state)
		{
			case CLIENT_STARTING:
				#ifdef DEBUG
				printf("[cliente=%d] connection_client_handler(EVENT_WRITE):CLIENT_STARTING\n",
						event->fd);
				#endif

				if(socket_write_all(event->fd, data, strlen(data)) == -1)
				{
					perror("connection_client_handler():");
					return -1;
				}

				client->state = CLIENT_ACTIVE;
				break;
			case CLIENT_ACTIVE:
				// Servir con contenido al cliente.
				#ifdef DEBUG
				fprintf(stderr, "[cliente=%d] connection_client_handler(EVENT_WRITE):CLIENT_ACTIVE\n",
						event->fd);
				#endif

				ret = stream_read(server.stream, client->offset,
						server.buffer_size, &buffer);

				if(ret == -1)
				{
					perror("connection_client_handler():");
					return -1;
				}

				#ifdef BANDWIDTH_THROTTLING
				#include <sys/time.h>

				struct timeval now;
				if(gettimeofday(&now, NULL) == -1)
				{
					perror("connection_client_handler():");
					return -1;
				}

				static inline int
				difftime(struct timeval *t1, struct timeval *t2, useconds_t interval)
				{
					// Si hay diferencia de segundos devolver que si paso el
					// intervalo ya que este es medido en usecs.
					if(t2->tv_sec - t1->tv_sec)
						return 1;

					// si la diff entre usecs es mayor o igual que interval
					// podemos enviar
					return ((t2->tv_usec - t1->tv_usec) >= interval) ? 1 : 0;
				}

				if(!difftime(&client->last_write_ts, &now, interval))
				{
					// El intervalo no paso, hacemos que se sirva otro socket
					return 0;
				}
				#endif

				// Podriamos haber usado socket_write_all pero no me convence, por que
				// si fallo, es por algo y de ultima eso lo manejamos con el offset del cliente
				// y los datos se los reenviamos.
				ret = socket_write(event->fd, buffer, server.buffer_size);
				if(ret == -1)
				{
					perror("connection_client_handler():");
					return -1;
				}

				#ifdef BANDWIDTH_THROTTLING
				if(gettimeofday(&client->last_write_ts, NULL) == -1)
				{
					perror("connection_client_handler():");
					return -1;
				}
				#endif


				client->offset += ret;

				// Por ahora reiniciamos el streaming.
				if(client->offset == server.stream->size)
				{
					#ifdef DEBUG
					fprintf(stderr, "[cliente=%d] connection_client_handler(CLIENT_ACTIVE):EVENT_WRITE: Se llego al final del stream, reiniciando.\n"
							, event->fd);
					#endif

					client->offset = 0;
				}

				break;
			default:
				break;
		}
	}