void rcp_dict_send_as_command(
		rcp_type_ref type, rcp_data_ref data,
		rcp_connection_ref con)
{
	{
		struct cmd_set_value cmd;
		rcp_type_ref cmd_type=rcp_command_type(CMD_SET_VALUE);
		rcp_init(cmd_type, (rcp_data_ref)&cmd);
		cmd.command = rcp_string_new_rec(CMD_STR_SET_VALUE);
		cmd.loginID = 0;
		cmd.value = rcp_record_new(type);
		rcp_connection_send_data(con, cmd_type, (rcp_data_ref)&cmd);
		rcp_deinit(cmd_type, (rcp_data_ref)&cmd);
	}
	rcp_dict_ref dict = (rcp_dict_ref)data;
	rcp_dict_node_ref node = rcp_dict_begin(dict);
	rcp_type_ref key_type = rcp_dict_type_key_type(type);
	rcp_type_ref data_type = rcp_dict_type_data_type(type);

	while (node){
		struct cmd_set_value cmd;
		rcp_type_ref cmd_type=rcp_command_type(CMD_SET_VALUE);
		rcp_init(cmd_type, (rcp_data_ref)&cmd);
		cmd.command = rcp_string_new_rec(CMD_STR_SET_VALUE);
		cmd.loginID = 0;

		if (key_type == rcp_ref_type){
			rcp_copy(rcp_dict_type_key_type(type), 
					rcp_dict_node_key(type, node),
					(rcp_data_ref)&cmd.path);
		}
		else{
			cmd.path = rcp_record_new_with(key_type,
					rcp_dict_node_key(type, node));
		}

		if (data_type == rcp_ref_type){
			rcp_copy(rcp_dict_type_data_type(type), 
					rcp_dict_node_data(type, node),
					(rcp_data_ref)&cmd.value);
		}
		else{
			cmd.value = rcp_record_new_with(data_type,
					rcp_dict_node_data(type, node));
		}

		rcp_connection_send_data(con, cmd_type, (rcp_data_ref)&cmd);
		rcp_deinit(cmd_type, (rcp_data_ref)&cmd);

		node = rcp_dict_node_next(node);
	}
}
void rcp_array_send_as_command(
		rcp_type_ref type, rcp_data_ref data,
		rcp_connection_ref con)
{
	if (rcp_array_type_data_type(type) != rcp_ref_type){
		rcp_error("Unsupported array type.");
		return;
	}

	{
		struct cmd_set_value cmd_ini;
		rcp_type_ref cmd_type=rcp_command_type(CMD_SET_VALUE);
		rcp_init(cmd_type, (rcp_data_ref)&cmd_ini);
		cmd_ini.command = rcp_string_new_rec(CMD_STR_SET_VALUE);
		cmd_ini.loginID = 0;
		cmd_ini.value = rcp_record_new(type);
		rcp_connection_send_data(con, cmd_type, (rcp_data_ref)&cmd_ini);
		rcp_deinit(cmd_type, (rcp_data_ref)&cmd_ini);
	}

	rcp_record_ref tmp_record = rcp_record_new(type);
	rcp_array_ref tmp_array = (rcp_array_ref)rcp_record_data(tmp_record);
	rcp_record_ref *tmp_val;

	{
		rcp_record_ref null_rec = NULL;
		rcp_array_append_data(type, tmp_array, (rcp_data_ref)&null_rec);
		tmp_val = rcp_array_raw_data(tmp_array);
	}

	rcp_array_ref array = (rcp_array_ref)data;
	rcp_array_iterater_ref node = rcp_array_begin(array);
	
	struct cmd_replace_value cmd;
	rcp_type_ref cmd_type=rcp_command_type(CMD_REPLACE_VALUE);
	rcp_init(cmd_type, (rcp_data_ref)&cmd);
	cmd.command = rcp_string_new_rec(CMD_STR_REPLACE_VALUE);
	cmd.begin = -1;
	cmd.end = -1;
	cmd.loginID = 0;
	cmd.value = tmp_record;

	while (node){
		*tmp_val = *(rcp_record_ref*)rcp_array_iterater_data(node);
		rcp_connection_send_data(con, cmd_type, (rcp_data_ref)&cmd);
		node = rcp_array_iterater_next(type, array, node);
	}
	
	*tmp_val = NULL;
	rcp_deinit(cmd_type, (rcp_data_ref)&cmd);
}
void rcp_std_send_as_command(
		rcp_type_ref type, rcp_data_ref data,
		rcp_connection_ref con)
{
	struct cmd_set_value cmd_ini;
	rcp_type_ref cmd_type=rcp_command_type(CMD_SET_VALUE);
	rcp_init(cmd_type, (rcp_data_ref)&cmd_ini);
	cmd_ini.command = rcp_string_new_rec(CMD_STR_SET_VALUE);
	cmd_ini.loginID = 0;
	cmd_ini.value = rcp_record_new_with(type, data);
	rcp_connection_send_data(con, cmd_type, (rcp_data_ref)&cmd_ini);
	rcp_deinit(cmd_type, (rcp_data_ref)&cmd_ini);
}
Exemple #4
0
void rcp_array_copied(rcp_type_ref type, rcp_data_ref data)
{
    rcp_type_ref data_type = rcp_array_type_data_type(type);
    rcp_array_ref core = (rcp_array_ref)data;
    if (!rcp_array_owning_data(core))
        return;

    const void *old_data = core->array;
    const size_t old_data_count = core->data_count;

    rcp_init(type, data);
    rcp_array_resize(type, core, old_data_count);
    core->data_count = old_data_count;
    memcpy(core->array, old_data, old_data_count*data_type->size);
    int i;
    for (i = 0; i<old_data_count; i++) {
        rcp_copied(data_type, core->array+i*data_type->size);
    }
}
Exemple #5
0
void rcp_array_copy(
    rcp_type_ref type, rcp_data_ref src, rcp_data_ref dst)
{
    rcp_type_ref data_type = rcp_array_type_data_type(type);
    rcp_array_ref src_core = (rcp_array_ref)src;
    rcp_array_ref dst_core = (rcp_array_ref)dst;

    rcp_init(type, dst);//not required
    dst_core->array = malloc(type->size*src_core->data_count);
    dst_core->data_count = src_core->data_count;
    dst_core->capacity = src_core->capacity;

    int i;
    for (i = 0; i<src_core->data_count; i++) {
        size_t offset = i*data_type->size;
        rcp_data_ref src_data = src_core->array+offset;
        rcp_data_ref dst_data = dst_core->array+offset;
        rcp_copy(data_type, src_data, dst_data);
    }
}
Exemple #6
0
int main(int argc, char **argv) {
	// parse arguments
	int i;
	for (i = 0; i < MAX_INTREMOVED; i++)
		intremoved[i] = NULL;
		
	for (i = 1; i < argc; i++) {
		if (strcmp(argv[i], "-h") == 0) {
			help();
			return 0;
		}
		else if (strcmp(argv[i], "-r") == 0) {
			if (argc == (i + 1)) {
				help();
				return 1;
			}

			if (intremoved_cnt >= MAX_INTREMOVED) {
				help();
				return 1;
			}

			intremoved[intremoved_cnt++] = argv[++i];
		}
		else {
			fprintf(stderr, "Error: process %s, unrecognized argument\n", rcpGetProcName());
			help();
			return 1;
		}
	}
	
	// initialize rcp
	rcp_init(RCP_PROC_ROUTER);
	
	// set interface configuration in shared memory
	router_detect_interfaces();

	RcpPkt *pkt;
	pkt = malloc(sizeof(RcpPkt) + RCP_PKT_DATA_LEN);
	if (pkt == NULL) {
		fprintf(stderr, "Error: process %s, cannot allocate memory, exiting...\n", rcpGetProcName());
		return 1;
	}
	
	// delete all static routes - default routes are not deleted
	int v = system("/opt/rcp/bin/rtclean static >> /opt/rcp/var/log/restart");
	if (v == -1) {
		fprintf(stderr, "Error: process %s, cannot delete existing static routes, exiting...\n", rcpGetProcName());
		return 1;
	}

	// receive loop
	int reconnect_timer = 0;
	struct timeval ts;
	ts.tv_sec = 1; // 1 second
	ts.tv_usec = 0;

	// use this timer to speed up rx loop when the system is busy
	uint32_t rcptic = rcpTic();

	// forever
	while (1) {
		// reconnect mux socket if connection failed
		if (reconnect_timer >= 5) {
			ASSERT(muxsock == 0);
			muxsock = rcpConnectMux(RCP_PROC_ROUTER, NULL, NULL, NULL);
			if (muxsock == 0)
				reconnect_timer = 1; // start reconnect timer
			else {
				reconnect_timer = 0;
				pstats->mux_reconnect++;
			}
		}

		fd_set fds;
		FD_ZERO(&fds);
		if (muxsock != 0)
			FD_SET(muxsock, &fds);
		int maxfd = muxsock;

		// wait for data
		errno = 0;
		int nready = select(maxfd + 1, &fds, (fd_set *) 0, (fd_set *) 0, &ts);
		if (nready < 0) {
			fprintf(stderr, "Error: process %s, select nready %d, errno %d\n",
				rcpGetProcName(), nready, errno);
		}
		else if (nready == 0) {
			// watchdog
			pstats->wproc++;

			// one second timeout
			router_if_timeout();
				
			// muxsocket reconnect timeout
			if (muxsock == 0)
				reconnect_timer++;
			
			// reload ts
			rcptic++;
			if (rcpTic() > rcptic) {
				// speed up the clock
				ts.tv_sec = 0;
				ts.tv_usec = 800000;	// 0.8 seconds
				pstats->select_speedup++;
			}
			else {
				ts.tv_sec = 1; // 1 second
				ts.tv_usec = 0;
			}
		}
		else if (muxsock != 0 && FD_ISSET(muxsock, &fds)) {
			errno = 0;
			int nread = recv(muxsock, pkt, sizeof(RcpPkt), 0);
			if(nread < sizeof(RcpPkt) || errno != 0) {
//				printf("Error: process %s, muxsocket nread %d, errno %d, disconnecting...\n",
//					rcpGetProcName(), nread, errno);
				close(muxsock);
				muxsock = 0;
				continue;
			}

			// read the packet data
			if (pkt->data_len != 0) {
				nread += recv(muxsock, (unsigned char *) pkt + sizeof(RcpPkt), pkt->data_len, 0);
			}
			ASSERT(nread == sizeof(RcpPkt) + pkt->data_len);

			// process cli packet
			if (pkt->type == RCP_PKT_TYPE_CLI && pkt->destination == RCP_PROC_ROUTER) {
				processCli(pkt);
				// forward the response back
				send(muxsock, pkt, sizeof(RcpPkt) + pkt->data_len, 0);
			}
			else
				ASSERT(0);
			
			
		}
		
	}
	return 0;
}
Exemple #7
0
int main(int argc, char **argv) {
//rcpDebugEnable();
	
	// initialize rcplib
	rcp_init(RCP_PROC_ACL);

	RcpPkt *pkt;
	pkt = malloc(sizeof(RcpPkt) + RCP_PKT_DATA_LEN);
	if (pkt == NULL) {
		fprintf(stderr, "Error: process %s, cannot allocate memory, exiting...\n", rcpGetProcName());
		exit(1);
	}
	
	// clear firewall table
	netfilter_generate();

	// receive loop
	int reconnect_timer = 0;
	struct timeval ts;
	ts.tv_sec = 1; // 1 second
	ts.tv_usec = 0;

	// use this timer to speed up rx loop when the system is busy
	uint32_t rcptic = rcpTic();

	while (1) {
		// reconnect mux socket if connection failed
		if (reconnect_timer >= 5) {
			ASSERT(muxsock == 0);
			muxsock = rcpConnectMux(RCP_PROC_ACL, NULL, NULL, NULL);
			if (muxsock == 0)
				reconnect_timer = 1; // start reconnect timer
			else {
				reconnect_timer = 0;
				pstats->mux_reconnect++;
			}
		}

		// set descriptors
		fd_set fds;
		FD_ZERO(&fds);
		int maxfd = 0;
		if (muxsock != 0) {
			FD_SET(muxsock, &fds);
			maxfd = (muxsock > maxfd)? muxsock: maxfd;
		}

		// wait for data
		errno = 0;
		int nready = select(maxfd + 1, &fds, (fd_set *) 0, (fd_set *) 0, &ts);
		if (nready < 0) {
			fprintf(stderr, "Error: process %s, select nready %d, errno %d\n",
				rcpGetProcName(), nready, errno);
		}
		else if (nready == 0) {
			// watchdog
			pstats->wproc++;

			// muxsocket reconnect timeout
			if (reconnect_timer > 0)
				reconnect_timer++;
			
			// netfilter update
			if (netfilter_update > 0) {
				if (--netfilter_update == 0)
					netfilter_generate();
			}
			
			// reload ts
			rcptic++;
			if (rcpTic() > rcptic) {
				// speed up the clock
				ts.tv_sec = 0;
				ts.tv_usec = 800000;	// 0.8 seconds
				pstats->select_speedup++;
			}
			else {
				ts.tv_sec = 1; // 1 second
				ts.tv_usec = 0;
			}
		}
		// cli data
		else if (muxsock != 0 && FD_ISSET(muxsock, &fds)) {
			errno = 0;
			int nread = recv(muxsock, pkt, sizeof(RcpPkt), 0);
			if(nread < sizeof(RcpPkt) || errno != 0) {
//				fprintf(stderr, "Error: process %s, muxsocket nread %d, errno %d, disconnecting...\n",
//					rcpGetProcName(), nread, errno);
				close(muxsock);
				reconnect_timer = 1;
				muxsock = 0;
				continue;
			}
			// read the packet data
			if (pkt->data_len != 0) {
				nread += recv(muxsock, (unsigned char *) pkt + sizeof(RcpPkt), pkt->data_len, 0);
			}
			ASSERT(nread == sizeof(RcpPkt) + pkt->data_len);

			// process the cli packet
			if (pkt->type == RCP_PKT_TYPE_CLI && pkt->destination == RCP_PROC_ACL) {
				processCli(pkt);
				// forward the packet back to rcp
				send(muxsock, pkt, sizeof(RcpPkt) + pkt->data_len, 0);
			}
			else
				ASSERT(0);
			
			
		}
		else
			ASSERT(0);

	}

	return 0;
}
Exemple #8
0
int main(int argc, char **argv) {
//rcpDebugEnable();
	
	// initialize shared memory
	rcp_init(RCP_PROC_DNS);

	RcpPkt *pkt;
	pkt = malloc(sizeof(RcpPkt) + RCP_PKT_DATA_LEN);
	if (pkt == NULL) {
		fprintf(stderr, "Error: process %s, cannot allocate memory, exiting...\n", rcpGetProcName());
		exit(1);
	}



	struct stat s;
	if (stat("/opt/rcp/var/log/dnsproxy_at_startup", &s) == 0)
		proxy_disabled = 1;


	// open sockets if necessary
	if (shm->config.dns_server) {
		if (proxy_disabled) {		
			rcpLog(muxsock, RCP_PROC_DNS, RLOG_WARNING, RLOG_FC_DNS,
				"an external DNS proxy is already running on the system, RCP DNS proxy will be disabled");
		}
		else {
			client_sock = rx_open(DNS_SERVER_PORT); // the socket open to clients listens on the server socket
	
			if (client_sock == 0) {
				fprintf(stderr, "Error: process %s, cannot open sockets, exiting...\n", rcpGetProcName());
				exit(1);
			}
		}
	}
	
	// set the static cache entries
	cache_update_static();
	
	
	// drop privileges
	rcpDropPriv();
	
	// initialize request list
	rq_list_init();
	
	// receive loop
	int reconnect_timer = 0;
	struct timeval ts;
	ts.tv_sec = 1; // 1 second
	ts.tv_usec = 0;

	// use this timer to speed up rx loop when the system is busy
	uint32_t rcptic = rcpTic();

	while (1) {
		// reconnect mux socket if connection failed
		if (reconnect_timer >= 10) {
			// a regular reconnect will fail, this process runs with dropped privileges
			// end the process and restart it again
			break;
		}

		// set descriptors
		fd_set fds;
		FD_ZERO(&fds);
		int maxfd = 0;
		if (muxsock != 0) {
			FD_SET(muxsock, &fds);
			maxfd = (muxsock > maxfd)? muxsock: maxfd;
		}
		if (client_sock != 0) {
			FD_SET(client_sock, &fds);
			maxfd = (client_sock > maxfd)? client_sock: maxfd;
		}
		
		// set all server sockets
		DnsReq *rq = rq_active();
		while (rq) {
			if (rq->sock != 0) {
				FD_SET(rq->sock, &fds);
				maxfd = (rq->sock > maxfd)? rq->sock: maxfd;
			}

			rq = rq->next;
		}

		// wait for data
		errno = 0;
		int nready = select(maxfd + 1, &fds, (fd_set *) 0, (fd_set *) 0, &ts);
		if (nready < 0) {
			fprintf(stderr, "Error: process %s, select nready %d, errno %d\n",
				rcpGetProcName(), nready, errno);
		}
		else if (nready == 0) {
			// watchdog
			pstats->wproc++;

			// muxsocket reconnect timeout
			if (reconnect_timer > 0)
				reconnect_timer++;
			
			// age cache entries
			cache_timer();
			
			// age request queue entries
			rq_timer();
			
			// reset rate-limit counter
			rate_limit = 0;
			
			// reload ts
			rcptic++;
			if (rcpTic() > rcptic) {
				// speed up the clock
				ts.tv_sec = 0;
				ts.tv_usec = 800000;	// 0.8 seconds
				pstats->select_speedup++;
			}
			else {
				ts.tv_sec = 1; // 1 second
				ts.tv_usec = 0;
			}
		}
		// cli data
		else if (muxsock != 0 && FD_ISSET(muxsock, &fds)) {
			errno = 0;
			int nread = recv(muxsock, pkt, sizeof(RcpPkt), 0);
			if(nread < sizeof(RcpPkt) || errno != 0) {
//				fprintf(stderr, "Error: process %s, muxsocket nread %d, errno %d, disconnecting...\n",
//					rcpGetProcName(), nread, errno);
				close(muxsock);
				reconnect_timer = 1;
				muxsock = 0;
				continue;
			}
			// read the packet data
			if (pkt->data_len != 0) {
				nread += recv(muxsock, (unsigned char *) pkt + sizeof(RcpPkt), pkt->data_len, 0);
			}
			ASSERT(nread == sizeof(RcpPkt) + pkt->data_len);

			// process the cli packet
			if (pkt->type == RCP_PKT_TYPE_CLI && pkt->destination == RCP_PROC_DNS) {
				processCli(pkt);
				// forward the packet back to rcp
				send(muxsock, pkt, sizeof(RcpPkt) + pkt->data_len, 0);
			}
			// dns updates packet
			else if (pkt->type == RCP_PKT_TYPE_UPDATEDNS) {
				rcpLog(muxsock, RCP_PROC_DNS, RLOG_DEBUG, RLOG_FC_IPC,
					"processing DNS updates packet");
				cache_update_static();
			}
			
			else
				ASSERT(0);
			
			
		}
		// DNS packets from clients
		else if (client_sock != 0 && FD_ISSET(client_sock, &fds)) {
			rx_packet(client_sock);
		}
		// DNS packets from servers
		else {
			DnsReq *rq = rq_active();
			while (rq) {
				if (rq->sock != 0 && FD_ISSET(rq->sock, &fds)) {
					rx_packet(rq->sock);
					break;
				}
				rq = rq->next;
			}
		}

		if (force_restart) {
			rcpLog(muxsock, RCP_PROC_DNS, RLOG_NOTICE, RLOG_FC_IPC,
				"process %s exiting for configuration purposes", rcpGetProcName());
			if (pstats->wmonitor != 0)
				pstats->wproc = pstats->wmonitor;	// tigger a restart in the next monitoring cycle
			pstats->no_logging = 1;
			break; // exit from while(1)
		}
		
		if (force_shutdown)
			break;

	}
	
	fflush(0);
	sleep(1);
	
	// close sockets
	if (muxsock != 0) {
		close(muxsock);
	}
	if (client_sock != 0) {
		close(client_sock);
	}
	
	// remove cli memory
	cliRemoveFunctions();

	// clear request memory
	rq_clear_inactive();
	// remove cache memory	
	cache_clear();
	
	// remove packet memory
	if (pkt)
		free(pkt);
	
	return 0;
}