Esempio n. 1
0
/** @brief Close an unicast connection and delete the client
 *
 * @param unicast_vars the unicast parameters
 * @param fds The polling file descriptors
 * @param Socket The socket of the client we want to disconnect
 */
void unicast_close_connection(unicast_parameters_t *unicast_vars, fds_t *fds, int Socket)
{

	int actual_fd;
	actual_fd=0;
	//We find the FD correspondig to this client
	while((actual_fd<fds->pfdsnum) && (fds->pfds[actual_fd].fd!=Socket))
		actual_fd++;

	if(actual_fd==fds->pfdsnum)
	{
		log_message( log_module, MSG_ERROR,"close connection : we did't find the file descriptor this should never happend, please contact\n");
		actual_fd=0;
		//We find the FD correspondig to this client
		while(actual_fd<fds->pfdsnum)
		{
			log_message( log_module, MSG_ERROR,"fds->pfds[actual_fd].fd %d Socket %d \n", fds->pfds[actual_fd].fd,Socket);
			actual_fd++;
		}
		return;
	}

	log_message( log_module, MSG_FLOOD,"We close the connection\n");
	//We delete the client
	unicast_del_client(unicast_vars, unicast_vars->fd_info[actual_fd].client);
	//We move the last fd to the actual/deleted one, and decrease the number of fds by one
	fds->pfds[actual_fd].fd = fds->pfds[fds->pfdsnum-1].fd;
	fds->pfds[actual_fd].events = fds->pfds[fds->pfdsnum-1].events;
	fds->pfds[actual_fd].revents = fds->pfds[fds->pfdsnum-1].revents;
	//we move the file descriptor information
	unicast_vars->fd_info[actual_fd] = unicast_vars->fd_info[fds->pfdsnum-1];
	//last one set to 0 for poll()
	fds->pfds[fds->pfdsnum-1].fd=0;
	fds->pfds[fds->pfdsnum-1].events=POLLIN|POLLPRI;
	fds->pfds[fds->pfdsnum-1].revents=0; //We clear it to avoid nasty bugs ...
	fds->pfdsnum--;
	fds->pfds=realloc(fds->pfds,(fds->pfdsnum+1)*sizeof(struct pollfd));
	if (fds->pfds==NULL)
	{
		log_message( log_module, MSG_ERROR,"Problem with realloc : %s file : %s line %d\n",strerror(errno),__FILE__,__LINE__);
		set_interrupted(ERROR_MEMORY<<8);
	}
	unicast_vars->fd_info=realloc(unicast_vars->fd_info,(fds->pfdsnum)*sizeof(unicast_fd_info_t));
	if (unicast_vars->fd_info==NULL)
	{
		log_message( log_module, MSG_ERROR,"Problem with realloc : %s file : %s line %d\n",strerror(errno),__FILE__,__LINE__);
		set_interrupted(ERROR_MEMORY<<8);
	}
	log_message( log_module, MSG_FLOOD,"Number of clients : %d\n", unicast_vars->client_number);

}
Esempio n. 2
0
/** @brief Handle an "event" on the unicast file descriptors
 * If the event is on an already open client connection, it handle the message
 * If the event is on the master connection, it accepts the new connection
 * If the event is on a channel specific socket, it accepts the new connection and starts streaming
 *
 */
int unicast_handle_fd_event(unicast_parameters_t *unicast_vars, fds_t *fds, mumudvb_channel_t *channels, int number_of_channels, strength_parameters_t *strengthparams, auto_p_t *auto_p, void *cam_p, void *scam_vars)
{
	int iRet;
	//We look what happened for which connection
	int actual_fd;


	for(actual_fd=1;actual_fd<fds->pfdsnum;actual_fd++)
	{
		iRet=0;
		if((fds->pfds[actual_fd].revents&POLLHUP)&&(unicast_vars->fd_info[actual_fd].type==UNICAST_CLIENT))
		{
			log_message( log_module, MSG_DEBUG,"We've got a POLLHUP. Actual_fd %d socket %d we close the connection \n", actual_fd, fds->pfds[actual_fd].fd );
			unicast_close_connection(unicast_vars,fds,fds->pfds[actual_fd].fd);
			//We check if we hage to parse fds->pfds[actual_fd].revents (the last fd moved to the actual one)
			if(fds->pfds[actual_fd].revents)
				actual_fd--;//Yes, we force the loop to see it
		}
		if((fds->pfds[actual_fd].revents&POLLIN)||(fds->pfds[actual_fd].revents&POLLPRI))
		{
			if((unicast_vars->fd_info[actual_fd].type==UNICAST_MASTER)||
					(unicast_vars->fd_info[actual_fd].type==UNICAST_LISTEN_CHANNEL))
			{
				//Event on the master connection or listenin channel
				//New connection, we accept the connection
				log_message( log_module, MSG_FLOOD,"New client\n");
				int tempSocket;
				unicast_client_t *tempClient;
				//we accept the incoming connection
				tempClient=unicast_accept_connection(unicast_vars, fds->pfds[actual_fd].fd);

				if(tempClient!=NULL)
				{
					tempSocket=tempClient->Socket;
					fds->pfdsnum++;
					fds->pfds=realloc(fds->pfds,(fds->pfdsnum+1)*sizeof(struct pollfd));
					if (fds->pfds==NULL)
					{
						log_message( log_module, MSG_ERROR,"Problem with realloc : %s file : %s line %d\n",strerror(errno),__FILE__,__LINE__);
						set_interrupted(ERROR_MEMORY<<8);
						return -1;
					}
					//We poll the new socket
					fds->pfds[fds->pfdsnum-1].fd = tempSocket;
					fds->pfds[fds->pfdsnum-1].events = POLLIN | POLLPRI | POLLHUP; //We also poll the deconnections
					fds->pfds[fds->pfdsnum-1].revents = 0;
					fds->pfds[fds->pfdsnum].fd = 0;
					fds->pfds[fds->pfdsnum].events = POLLIN | POLLPRI;
					fds->pfds[fds->pfdsnum].revents = 0;

					//Information about the descriptor
					unicast_vars->fd_info=realloc(unicast_vars->fd_info,(fds->pfdsnum)*sizeof(unicast_fd_info_t));
					if (unicast_vars->fd_info==NULL)
					{
						log_message( log_module, MSG_ERROR,"Problem with realloc : %s file : %s line %d\n",strerror(errno),__FILE__,__LINE__);
						set_interrupted(ERROR_MEMORY<<8);
						return -1;
					}
					//client connection
					unicast_vars->fd_info[fds->pfdsnum-1].type=UNICAST_CLIENT;
					unicast_vars->fd_info[fds->pfdsnum-1].channel=-1;
					unicast_vars->fd_info[fds->pfdsnum-1].client=tempClient;


					log_message( log_module, MSG_FLOOD,"Number of clients : %d\n", unicast_vars->client_number);

					if(unicast_vars->fd_info[actual_fd].type==UNICAST_LISTEN_CHANNEL)
					{
						//Event on a channel connection, we open a new socket for this client and
						//we store the wanted channel for when we will get the GET
						log_message( log_module, MSG_DEBUG,"Connection on a channel socket the client  will get the channel %d\n", unicast_vars->fd_info[actual_fd].channel);
						tempClient->askedChannel=unicast_vars->fd_info[actual_fd].channel;
					}
				}
			}
			else if(unicast_vars->fd_info[actual_fd].type==UNICAST_CLIENT)
			{
				//Event on a client connectio i.e. the client asked something
				log_message( log_module, MSG_FLOOD,"New message for socket %d\n", fds->pfds[actual_fd].fd);
				iRet=unicast_handle_message(unicast_vars,unicast_vars->fd_info[actual_fd].client, channels, number_of_channels, strengthparams, auto_p, cam_p, scam_vars);
				if (iRet==-2 ) //iRet==-2 --> 0 received data or error, we close the connection
				{
					unicast_close_connection(unicast_vars,fds,fds->pfds[actual_fd].fd);
					//We check if we hage to parse fds->pfds[actual_fd].revents (the last fd moved to the actual one)
					if(fds->pfds[actual_fd].revents)
						actual_fd--;//Yes, we force the loop to see it again
				}
			}
			else
			{
				log_message( log_module, MSG_WARN,"File descriptor with bad type, please contact\n Debug information : actual_fd %d unicast_vars->fd_info[actual_fd].type %d\n",
						actual_fd, unicast_vars->fd_info[actual_fd].type);
			}
		}
	}
	return 0;

}
Esempio n. 3
0
/**
 * 操作系统级抽象线程
 */
OSThread::OSThread(OSThreadStartFunc start_proc, void* start_parm) {
  pd_initialize();
  set_start_proc(start_proc);
  set_start_parm(start_parm);
  set_interrupted(false);
}