Esempio n. 1
0
File: plug.c Progetto: easymc/easymc
int emc_connect(int plug, ushort mode, const char * ip, const ushort port){
	struct easymc_plug * pg = (struct easymc_plug *)global_get_plug(plug);
	if(!pg){
		errno = ENOPLUG;
		return -1;
	}
	if(pg->ipc_ || pg->tcp_){
		errno = EREBIND;
		return -1;
	}
	if(EMC_PUB == mode)mode = EMC_SUB;
	if(EMC_REP == mode)mode = EMC_REQ;
	pg->mode = mode;
	if(!get_device_tcp_mgr(pg->device)){
		set_device_tcp_mgr(pg->device, create_tcp_mgr(pg->device, get_device_thread(pg->device)));
	}
	if(!get_device_tcp_mgr(pg->device)){
		return -1;
	}
	if(!ip || check_local_machine(inet_addr(ip))){
		pg->ipc_ = create_ipc(inet_addr(ip), port, pg->device, plug, mode, EMC_REMOTE);
		if(!pg->ipc_){
			return -1;
		}
	}else{
		pg->tcp_ = add_tcp(inet_addr(ip), port, mode, EMC_REMOTE, plug, get_device_tcp_mgr(pg->device));
		if(!pg->tcp_){
			delete_tcp(pg->tcp_);
			pg->tcp_ = NULL;
			return -1;
		}
	}
	return 0;
}
Esempio n. 2
0
File: plug.c Progetto: easymc/easymc
int emc_close(int plug){
	int index = 0;
	void * msg = NULL;
	struct easymc_plug * pg = NULL;
	
	pg = (struct easymc_plug *)global_get_plug(plug);
	if(!pg){
		errno = ENOPLUG;
		return -1;
	}
	del_device_plug(pg->device, plug);
	for(index = 0; index < 0xFFFF; index ++){
		post_ringqueue(pg->mq);
	}
	if(pg->ipc_){
		delete_ipc(pg->ipc_);
	}
	if(pg->tcp_){
		delete_tcp(pg->tcp_);
	}
	while(1){
		if(pop_ringqueue_multiple(pg->mq, (void **)&msg) < 0){
			break;
		}else{
			emc_msg_free(msg);
		}
	}
	delete_ringqueue(pg->mq);
	free(pg);
	global_erase_plug(plug);
	return 0;
}
Esempio n. 3
0
int fire_worker_start(int queue_id)
{
	int ret, i, j, k, prot, send_ret;

	fire_worker_t *cc = &(workers[queue_id]); 
	assert(ps_init_handle(&(cc->server_handle)) == 0);
	assert(ps_init_handle(&(cc->client_handle)) == 0);

	struct ps_queue server_queue, client_queue;
	server_queue.ifindex = config->server_ifindex;
	server_queue.qidx = queue_id;
	client_queue.ifindex = config->client_ifindex;
	client_queue.qidx = queue_id;

	assert(ps_attach_rx_device(&(cc->server_handle), &server_queue) == 0);
	assert(ps_attach_rx_device(&(cc->client_handle), &client_queue) == 0);

	struct ps_chunk client_chunk, send_client_chunk, server_chunk, send_server_chunk;
	assert(ps_alloc_chunk(&(cc->client_handle), &client_chunk) == 0);
	assert(ps_alloc_chunk(&(cc->client_handle), &send_client_chunk) == 0);
	assert(ps_alloc_chunk(&(cc->server_handle), &server_chunk) == 0);
	assert(ps_alloc_chunk(&(cc->server_handle), &send_server_chunk) == 0);

	client_chunk.queue.ifindex = config->client_ifindex;
	client_chunk.queue.qidx = queue_id;
	send_client_chunk.queue.ifindex = config->client_ifindex;
	send_client_chunk.queue.qidx = queue_id;
	server_chunk.queue.ifindex = config->server_ifindex;
	server_chunk.queue.qidx = queue_id;
	send_server_chunk.queue.ifindex = config->server_ifindex;
	send_server_chunk.queue.qidx = queue_id;

	int num_pkt_to_client = 0, num_pkt_to_server = 0;
	int pret;

	gettimeofday(&(cc->startime), NULL);

#if defined(HIPAC_TCB)
	int hipac_cnt = 0;
#endif

	for (;;) {
		num_pkt_to_client = 0;
		num_pkt_to_server = 0;
		j = 0;
		k = 0;

		client_chunk.cnt = config->io_batch_num;
		client_chunk.recv_blocking = 0;

		ret = ps_recv_chunk(&(cc->client_handle), &client_chunk);
		if (ret <= 0) {
			/* Receive nothing from server, go to the start of the loop to process client again */
			goto process_server;
		}
		cc->total_packets += ret;

		int action;

		for (i = 0; i < ret; i ++) {
			prot = process_packet(client_chunk.buf + client_chunk.info[i].offset, client_chunk.info[i].len);
			switch (prot) {
				case TCP_SYN_SENT:
					action = HiPAC(client_chunk.buf + client_chunk.info[i].offset, client_chunk.info[i].len, l);
					if(action == FORWARD) {
						// first handshake packet
						// construct the response, and send back to client
						//fprint(INFO, "1) TCP_SYN_SENT\n");
						send_client_chunk.info[j].len = client_chunk.info[i].len;
						send_client_chunk.info[j].offset = j * PS_MAX_PACKET_SIZE;
						memcpy(send_client_chunk.buf + send_client_chunk.info[j].offset,
								client_chunk.buf + client_chunk.info[i].offset, client_chunk.info[i].len);
						form_syn_response(send_client_chunk.buf + send_client_chunk.info[j].offset,
								send_client_chunk.info[j].len);
						pret = process_packet(send_client_chunk.buf 
								+ send_client_chunk.info[j].offset, send_client_chunk.info[j].len);
#if 0
						if(pret != TCP_SYN_RECV){
							printf("pret is %d\n", pret);
							printf("client:\n");
							dmesg(client_chunk.buf + client_chunk.info[i].offset);
							printf("server:\n");
							dmesg(send_client_chunk.buf + send_client_chunk.info[j].offset);
							exit(0);
						}
#endif
						assert(pret == TCP_SYN_RECV);
						//fprint(INFO, "2) TCP_SYN_RECV\n");
						j ++;
					}
					else{ 
					//	hipac_cnt ++;
					//	if(hipac_cnt > 0) printf("hipac filter : %d\n", hipac_cnt);
						delete_tcp(client_chunk.buf + client_chunk.info[i].offset);
					}			
					break;

				case TCP_ESTABLISHED:
					// the 3rd handshake packet
					// do nothing and wait for client's real request
					//fprint(INFO, "3) TCP_ESTABLISHED\n");
					break;

				case -2:
					//fprint(INFO, "two buckets full\n");
					break;

				case -1:
					//fprint(INFO, "Error pkt, don't forward to server.\n");
					break;

				default:
					// normal packet, send to server
					//fprint(INFO, "4) Normal packet, send to server\n");
					send_server_chunk.info[k].len = client_chunk.info[i].len;
					send_server_chunk.info[k].offset = k * PS_MAX_PACKET_SIZE;
					memcpy(send_server_chunk.buf + send_server_chunk.info[k].offset,
							client_chunk.buf + client_chunk.info[i].offset, client_chunk.info[i].len);
					k ++;
					break;
			}

			cc->total_bytes += client_chunk.info[i].len; 

		}
	
		if (j > 0) {
			//fprint(INFO, "sending %d SYN/ACK packet to client, queue_id %d, ifindex %d\n", j, queue_id, config->client_ifindex);
			send_client_chunk.cnt = j;
			send_ret = ps_send_chunk(&(cc->client_handle), &send_client_chunk);
			if (send_ret < 0)
				fprint(ERROR, "send packet fail, ret = %d\n", send_ret);
		}

		if (k > 0) {
			//fprint(INFO, "sending %d packets of established connection to server, queue_id %d, ifindex %d\n", k, queue_id, config->server_ifindex);
			send_server_chunk.cnt = k;
			send_ret = ps_send_chunk(&(cc->server_handle), &send_server_chunk);
			if (send_ret < 0)
				fprint(ERROR, "send packet fail, ret = %d\n", send_ret);
		}
#if 0
		/* FIXME: cannot send all packets
		while (ret > 0) {
			chunk.cnt = ret;
			send_ret = ps_send_chunk(&(cc->handle), &send_chunk);
			if (send_ret < 0)
				fprint(ERROR, "send packet fail, ret = %d\n", send_ret);
			ret -= send_ret;
			//assert(ret >= 0);
		}*/
#endif

process_server:
		/*----------------------------------------------------------------------------------*/
		/* Now process server side packet*/
		server_chunk.cnt = config->io_batch_num;
		//server_chunk.recv_blocking = 0;	//modify at the frist time

		server_chunk.recv_blocking = 0;
		j = 0;

		ret = ps_recv_chunk(&(cc->server_handle), &server_chunk);
		if (ret <= 0) {
			if (errno == EINTR)
				continue;
			/* Receive nothing from server, go to the start of the loop to process client again */
			continue;
		}
		for (i = 0; i < ret; i ++) {
			prot = process_packet(server_chunk.buf + server_chunk.info[i].offset, server_chunk.info[i].len);
			if (prot == 0) {
				send_client_chunk.info[j].len = server_chunk.info[i].len;
				send_client_chunk.info[j].offset = j * PS_MAX_PACKET_SIZE;
				memcpy(send_client_chunk.buf + send_client_chunk.info[j].offset,
					server_chunk.buf + server_chunk.info[i].offset, server_chunk.info[i].len);
				j ++;
			} else {
				fprint(ERROR, "wrong packet from server\n");
			}
		}

		if (j > 0) {
			fprint(DEBUG, "sending packet, queue_id %d, num %d, index %d\n", queue_id, ret, config->client_ifindex);
			send_client_chunk.cnt = j;
			send_ret = ps_send_chunk(&(cc->client_handle), &send_client_chunk);
			if (send_ret < 0)
				fprint(ERROR, "send packet fail, ret = %d\n", send_ret);
		}
	}
	return 0;
}