Пример #1
0
void
p2pRequest(struct session *session_a, struct session *session_b)
{

	char		*ip_a;
	char		*ip_b;
	uint32_t	 port;
	DNDSMessage_t	*msg;

	if (session_a->netc == NULL || session_b->netc == NULL) {
		return;
	}

	if (!strcmp(session_a->netc->peer->host, session_b->netc->peer->host)) {
		ip_a = session_a->ip_local;
		ip_b = session_b->ip_local;
	} else {
		ip_a = session_a->netc->peer->host;
		ip_b = session_b->netc->peer->host;
	}

	 /* basic random port : 49152–65535 */
	port = rand() % (65535-49152+1)+49152;

	jlog(L_DEBUG, "node A ip public %s", ip_a);
	jlog(L_DEBUG, "node B ip public %s", ip_b);

	/* msg session A */
	DNDSMessage_new(&msg);
	DNDSMessage_set_pdu(msg, pdu_PR_dnm);

	DNMessage_set_operation(msg, dnop_PR_p2pRequest);

	P2pRequest_set_macAddrDst(msg, session_b->tun_mac_addr);
	P2pRequest_set_ipAddrDst(msg, ip_b);
	P2pRequest_set_port(msg, port);
	P2pRequest_set_side(msg, P2pSide_client);

	net_send_msg(session_a->netc, msg);
	DNDSMessage_del(msg);

	/* msg session B */
	DNDSMessage_new(&msg);
	DNDSMessage_set_pdu(msg, pdu_PR_dnm);

	DNMessage_set_operation(msg, dnop_PR_p2pRequest);

	P2pRequest_set_macAddrDst(msg, session_a->tun_mac_addr);
	P2pRequest_set_ipAddrDst(msg, ip_a);
	P2pRequest_set_port(msg, port);
	P2pRequest_set_side(msg, P2pSide_server);

	net_send_msg(session_b->netc, msg);
	DNDSMessage_del(msg);

}
Пример #2
0
int send_msg_to_switch(Csprite* p, uint16_t cmd, userid_t sender_id ,Cmessage * c_in)
{
	//Common buffer for sending package to switch

	//Connect to switch and send init package in case of disconnection
	if (switch_fd == -1) {
		connect_to_switch();
	}
	
	if ((switch_fd == -1)  ) {	
		KDEBUG_LOG(sender_id, "FAILED SENDING PACKAGE TO SWITCH\t[switch_fd=%d]", switch_fd);
		return 0;
	}

	//Build the package
	static uint8_t sw_pkg[sizeof(switch_proto_t) ];
	switch_proto_t* pkg = (switch_proto_t*)sw_pkg;
	pkg->len = sizeof(switch_proto_t );
	pkg->seq = (p ? ((p->fdsess->fd) << 16) | (p->get_waitcmd()) : 0); // set higher 16 bytes fd and lower 16 bytes waitcmd
	pkg->cmd = cmd;
	pkg->ret = 0;
	pkg->sender_id  = sender_id;
	if (p) {
		KDEBUG_LOG(p->id, "TO SW\t[cmd=%u waitcmd=%u]", cmd, p->get_waitcmd());
	}

	return net_send_msg(switch_fd , (char*)pkg , c_in   );
}
Пример #3
0
int send_msg_to_db_ex(Csprite* p, userid_t id, uint16_t cmd,  Cmessage * c_in )
{
	if (proxysvr_fd == -1) {
		proxysvr_fd = connect_to_service(config_get_strval("service_dbproxy"), 0, 65535, 1);
	}

	if ((proxysvr_fd == -1)	) {
		KDEBUG_LOG(id, "send to dbproxy failed: fd=%d ", proxysvr_fd );
		if (p) {
			if (p->get_waitcmd()== cli_login_cmd) {
				return -1;
			}
			return p->send_err( cli_err_system_error );
		}
		return 0;
	}
	static char dbbuf[ sizeof(db_proto_t) ];

	db_proto_t* pkg = (db_proto_t*)dbbuf;
	pkg->len = sizeof(db_proto_t);
	pkg->seq = (p ? ((p->fdsess->fd << 16) | p->get_waitcmd()) : 0);
	pkg->cmd = cmd;
	pkg->ret = 0;
	pkg->id  = id;
	KDEBUG_LOG(pkg->id,"SO[0x%04X]",pkg->cmd );

	return net_send_msg(proxysvr_fd, (char*)dbbuf, c_in   );
}
Пример #4
0
static void on_secure(netc_t *netc)
{
	struct session *session;
	session = netc->ext_ptr;

	if (session->state == SESSION_STATE_WAIT_STEPUP) {

		/* Set the session as authenticated */
		session->state = SESSION_STATE_AUTHED;

		/* Send a message to acknowledge the client */
		DNDSMessage_t *msg = NULL;
		DNDSMessage_new(&msg);
		DNDSMessage_set_channel(msg, 0);
		DNDSMessage_set_pdu(msg, pdu_PR_dnm);

		DNMessage_set_seqNumber(msg, 1);
		DNMessage_set_ackNumber(msg, 0);
		DNMessage_set_operation(msg, dnop_PR_authResponse);

		AuthResponse_set_result(msg, DNDSResult_success);
		net_send_msg(session->netc, msg);
		DNDSMessage_del(msg);

		context_add_session(session->context, session);
		jlog(L_DEBUG, "session id: %d", session->id);
	}
}
Пример #5
0
void transmit_netinfo_response(netc_t *netc)
{
	struct session *session = netc->ext_ptr;

	DNDSMessage_t *msg = NULL;
	DNDSMessage_new(&msg);
	DNDSMessage_set_channel(msg, 0);
	DNDSMessage_set_pdu(msg, pdu_PR_dnm);

	DNMessage_set_seqNumber(msg, 1);
	DNMessage_set_ackNumber(msg, 0);
	DNMessage_set_operation(msg, dnop_PR_netinfoResponse);

	net_send_msg(session->netc, msg);
	DNDSMessage_del(msg);
	transmit_node_connectinfo(ConnectState_connected,
				session->ip, session->cert_name);
}
Пример #6
0
/* Authentication Request from the node */
int
authRequest(struct session *session, DNDSMessage_t *req_msg)
{
	char		*certName = NULL;
	size_t	 	 length = 0;

	struct session *old_session = NULL;

	if (session->state != SESSION_STATE_NOT_AUTHED) {
		jlog(L_WARNING, "authRequest duplicate");
		return -1;
	}

	DNDSMessage_t *msg = NULL;

	DNDSMessage_new(&msg);
	DNDSMessage_set_channel(msg, 0);
	DNDSMessage_set_pdu(msg, pdu_PR_dnm);

	DNMessage_set_seqNumber(msg, 1);
	DNMessage_set_ackNumber(msg, 0);
	DNMessage_set_operation(msg, dnop_PR_authResponse);

	AuthRequest_get_certName(req_msg, &certName, &length);

	jlog(L_DEBUG, "URI:%s", certName);
	session->node_info = cn2node_info(certName);
	if (session->node_info == NULL) {
		jlog(L_WARNING, "cn2node_info failed");
		DNDSMessage_del(msg);
		return -1;
	}

//	jlog(L_DEBUG, "type: %s", session->node_info->type);
	jlog(L_DEBUG, "uuid: %s", session->node_info->uuid);
	jlog(L_DEBUG, "network_uuid: %s", session->node_info->network_uuid);
	jlog(L_DEBUG, "network_id: %s", session->node_info->network_id);
	jlog(L_DEBUG, "v: %d", session->node_info->v);

	if (session->node_info->v == 1) {
		session->vnetwork = vnetwork_lookup_id(session->node_info->network_id);
		if (session->vnetwork != NULL) {
			strncpy(session->node_info->network_uuid, session->vnetwork->uuid, 36);
			session->node_info->network_uuid[36] = '\0';
		}
	} else
		session->vnetwork = vnetwork_lookup(session->node_info->network_uuid);

	if (session->vnetwork == NULL) {
		AuthResponse_set_result(msg, DNDSResult_noRight);
		net_send_msg(session->netc, msg);
		DNDSMessage_del(msg);
		return -1;
	}

	/* check if the node's uuid is known
	if (ctable_find(session->context->atable, session->node_info->uuid) == NULL) {
		AuthResponse_set_result(msg, DNDSResult_noRight);
		net_send_msg(session->netc, msg);
		DNDSMessage_del(msg);
		jlog(L_ERROR, "authentication failed, invalid certificate");
		return -1;
	}
	*/

	/* check if the node is already connected */
	old_session = ctable_find(session->vnetwork->ctable, session->node_info->uuid);
//	if (old_session == NULL) {
		ctable_insert(session->vnetwork->ctable, session->node_info->uuid, session);
/*
	} else {
		// that node is already connected, if the new session is from the same IP
		// disconnect the old session, and let this one connect
		if (old_session->ip == NULL) {
			net_disconnect(old_session->netc);
			ctable_insert(session->vnetwork->ctable, session->node_info->uuid, session);
		} else if (strcmp(old_session->ip, session->ip) == 0) {
			net_disconnect(old_session->netc);
			ctable_insert(session->vnetwork->ctable, session->node_info->uuid, session);
		}
	}
*/

	session->cert_name = strdup(certName);
	if (session->netc->security_level == NET_UNSECURE) {

		AuthResponse_set_result(msg, DNDSResult_success);
		net_send_msg(session->netc, msg);

		session->state = SESSION_STATE_AUTHED;
		session->netc->on_secure(session->netc);

	} else {

		AuthResponse_set_result(msg, DNDSResult_secureStepUp);
		net_send_msg(session->netc, msg);

		krypt_add_passport(session->netc->kconn, session->vnetwork->passport);
		session->state = SESSION_STATE_WAIT_STEPUP;
		net_step_up(session->netc);
	}

	DNDSMessage_del(msg);

	return 0;
}
Пример #7
0
static void forward_ethernet(struct session *session, DNDSMessage_t *msg)
{
	uint8_t *frame;
	size_t frame_size;

	uint8_t macaddr_src[ETHER_ADDR_LEN];
	uint8_t macaddr_dst[ETHER_ADDR_LEN];
	uint8_t macaddr_dst_type;

	struct session *session_dst = NULL;
	struct session *session_src = NULL;
	struct session *session_list = NULL;

	if (session->state != SESSION_STATE_AUTHED)
		return;

	DNDSMessage_get_ethernet(msg, &frame, &frame_size);

	/* New mac address ? Add it to the lookup table */
	inet_get_mac_addr_src(frame, macaddr_src);
	session_src = ftable_find(session->context->ftable, macaddr_src);

	if (session_src == NULL) {
		memcpy(session->mac_addr, macaddr_src, ETHER_ADDR_LEN);
		ftable_insert(session->context->ftable, macaddr_src, session);
		session_src = session;
		session_add_mac(session, macaddr_src);
	}

	/* Lookup the destination */
	inet_get_mac_addr_dst(frame, macaddr_dst);
	macaddr_dst_type = inet_get_mac_addr_type(macaddr_dst);
	session_dst = ftable_find(session->context->ftable, macaddr_dst);

	if (session_src != NULL && session_dst != NULL &&
		(session_src == session_dst)) {
		/* prevent loops */
		return;
	}

	if (macaddr_dst_type == ADDR_MULTICAST) {
		/* Multicast is not supported yet */
		return;
	}

	/* Switch forwarding */
	if (macaddr_dst_type == ADDR_UNICAST		/* The destination address is unicast */
		&& session_dst != NULL
		&& session_dst->netc != NULL) {		/* AND the session is up */

			/*jlog(L_DEBUG, "forwarding the packet to [%s]", session_dst->ip);*/
			net_send_msg(session_dst->netc, msg);

			int lnk_state = 0;
			lnk_state = linkst_joined(session_src->context->linkst, session_src->id, session_dst->id);
			if (lnk_state != 1) {
				p2pRequest(session_src, session_dst);
				linkst_join(session_src->context->linkst, session_src->id, session_dst->id);
			}


	/* Switch flooding */
	} else if (macaddr_dst_type == ADDR_BROADCAST ||	/* This packet has to be broadcasted */
		session_dst == NULL)  {				/* OR the fib session is down */

			session_list = session->context->session_list;
			while (session_list != NULL) {
				net_send_msg(session_list->netc, msg);
				/*jlog(L_DEBUG, "flooding the packet to [%s]", session_list->ip);*/
				session_list = session_list->next;
			}
	} else {
		jlog(L_WARNING, "unknown packet");
	}
}
Пример #8
0
int
provisioning(json_t *jmsg)
{
	char		*cert;
	char		*ipaddr;
	char		*pkey;
	char		*response;
	char		*tcert;
	char		*tid;
	json_t		*node;
	struct session	*session;

	if (json_unpack(jmsg, "{s:s}", "response", &response) == -1) {
		jlog(L_ERROR, "json_unpack failed");
		return -1;
	}

	if (strcmp(response, "success") != 0) {
		jlog(L_ERROR, "provisioning != success");
		return -1;
	}

	if (json_unpack(jmsg, "{s:s}", "tid", &tid) == -1) {
		jlog(L_ERROR, "json_unpack failed");
		return -1;
	}

	if ((node = json_object_get(jmsg, "node")) == NULL) {
		jlog(L_ERROR, "json_object_get failed");
		return -1;
	}

	if (json_unpack(node, "{s:s}", "cert", &cert) == -1 ||
	    json_unpack(node, "{s:s}", "pkey", &pkey) == -1 ||
	    json_unpack(node, "{s:s}", "tcert", &tcert) == -1 ||
	    json_unpack(node, "{s:s}", "ipaddr", &ipaddr) == -1) {
		jlog(L_ERROR, "NULL parameter");
		return -1;
	}

	DNDSMessage_t *new_msg;
	DNDSMessage_new(&new_msg);
	DNDSMessage_set_channel(new_msg, 0);
	DNDSMessage_set_pdu(new_msg, pdu_PR_dnm);

	DNMessage_set_operation(new_msg, dnop_PR_provResponse);

	ProvResponse_set_certificate(new_msg, cert, strlen(cert));
	ProvResponse_set_certificateKey(new_msg, (uint8_t*)pkey, strlen(pkey));
	ProvResponse_set_trustedCert(new_msg, (uint8_t*)tcert, strlen(tcert));
	ProvResponse_set_ipAddress(new_msg, ipaddr);

	session = session_tracking_table[atoi(tid) % MAX_SESSION];
	session_tracking_table[atoi(tid) % MAX_SESSION] = NULL;
	if (session)
		net_send_msg(session->netc, new_msg);
	DNDSMessage_del(new_msg);

	/* XXX
	 * If the provisioning is not a success,
	 * we must disconnect the client.
	 */

	return 0;
}
Пример #9
0
int process_tch(struct session_info *s, struct l1ctl_burst_ind *bi, uint8_t *msg)
{
	int ret, ul;
	uint16_t arfcn;
	uint32_t fn;
	uint8_t conv_data[CONV_SIZE];
	struct burst_buf *bb;

	arfcn = ntohs(bi->band_arfcn);
	ul = !!(arfcn & ARFCN_UPLINK);
	fn = ntohl(bi->frame_nr);

	bb = &s->facch[ul];

	/* append data to message buffer */
	expand_msb(bi->bits, bb->data + bb->count * 114, 114);

	if(not_zero(s->key, 8)) {
		int i;
		uint8_t ks[114];
		if (ul)
			osmo_a5(1, s->key, fn, 0, ks);
		else
			osmo_a5(1, s->key, fn, ks, 0);

		for (i=0; i<114; i++) {
			bb->data[bb->count * 114 + i] ^= ks[i];
		}
	}

	// not used
	bb->sbit[bb->count * 2 + 0] = !!(bi->bits[14] & 0x10);
	bb->sbit[bb->count * 2 + 1] = !!(bi->bits[14] & 0x20);

	bb->snr[bb->count] = bi->snr;
	bb->rxl[bb->count] = bi->rx_level;

	/* check burst flags */
	switch (bi->bits[14] & 0x30) {
	case 0x00:
		/* TCH + TCH */
		//printf("TCH\n");
		/* voice blocks or flags corrupted */
		if (bb->count) {
			/* already had errors? */
			if (bb->errors < 2) {
				/* give a try and record error */
				bb->count++;
				bb->errors++;
			} else {
				/* discard all bursts in buffer */
				bb->count = 0;
				bb->errors = 0;
				return 0;
			}
		} else {
			/* process voice */
			return 0;
		}
		break;
	case 0x20:
		/* FACCH + TCH */
		//printf("FACCH+TCH\n");
		if (bb->count == 0) {
			/* start burst buffering */
			bb->count = 1;
		} else {
			/* check how many bursts in buffer */
			if (bb->count < 4) {
				/* all ok, append */
				bb->count++;
			} else {
				/* severely errored burst, other errors? */
				if (bb->errors < 2) {
					/* give a try and record error */
					bb->count++;
					bb->errors++;
				} else {
					/* discard all bursts in buffer */
					bb->count = 0;
					bb->errors = 0;
					return 0;
				}
			}
		}
		break;
	case 0x10:
		/* TCH + FACCH */
		//printf("TCH+FACCH\n");
		if (bb->count > 3) {
			/* all ok, append */
			bb->count++;
		} else {
			/* severely errored burst, other errors? */
			if (bb->errors < 2) {
				/* give a try and record error */
				bb->count++;
				bb->errors++;
			} else {
				/* discard all bursts in buffer */
				bb->count = 0;
				bb->errors = 0;
				return 0;
			}
		}
		break;
	case 0x30:
		/* FACCH + FACCH (or GPRS) */
		//printf("FACCH\n");
		if (bb->count > 3) {
			/* probably overlapping FACCHs */
			bb->count++;
			//record a & b facch separately
		} else {
			/* overlapping and misaligned? */
			bb->count++;
			bb->errors++;
		}
	}

	/* Return if not enough bursts for a full gsm message */
	if (bb->count == 8) {
		struct radio_message *m;

		/* try to decode FACCH */

		/* de-interleaving */
		gsm_deinter_facch(bb->data, conv_data);

		ret = decode_signalling(conv_data, msg);
		if (!ret) {
			/* skip one burst and wait next */
			// some circular buffer needed
			memcpy(bb->data, bb->data + 114, 7 * 114);
			memcpy(bb->sbit, bb->sbit + 2, 7 * 2);
			bb->count = 7;
			bb->errors /= 2; // approximated value
			return 0;
		}

		m = malloc(sizeof(struct radio_message));
		memcpy(&m->bb, bb, sizeof(*bb));
		m->chan_nr = bi->chan_nr;
		m->flags = MSG_FACCH|MSG_DECODED;
		if (s->have_key)
			m->flags |= MSG_CIPHERED;
		memcpy(m->msg, msg, 23);
		m->msg_len = 23;

		handle_lapdm(s, &s->chan_facch[ul], m->msg, m->msg_len, m->bb.fn[0], ul);

		net_send_msg(m);

		/* check overlapping status */
		if ((bi->bits[14] & 0x30) == 0x30) {
			/* start subsequent message processing */
			memcpy(bb->data, bb->data + 4 * 114, 4 * 114);
			memcpy(bb->sbit, bb->sbit + 4 * 2, 4 * 2);
			bb->count = 4;
			bb->errors /= 2; // approximated value
			memset(bb->data + bb->count*114, 0, sizeof(bb->data)/2);
		} else {
			/* nothing else in the buffer, reset */
			bb->count = 0;
			bb->errors = 0;
			memset(bb->data, 0, sizeof(bb->data));
		}

		return 23;
	}

	return 0;
}