Example #1
0
static gboolean listener_event(GIOChannel *channel, GIOCondition condition,
							gpointer user_data)
{
	GDHCPServer *dhcp_server = user_data;
	struct dhcp_packet packet;
	struct dhcp_lease *lease;
	uint32_t requested_nip = 0;
	uint8_t type, *server_id_option, *request_ip_option;
	int re;

	if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
		dhcp_server->listener_watch = 0;
		return FALSE;
	}

	re = dhcp_recv_l3_packet(&packet, dhcp_server->listener_sockfd);
	if (re < 0)
		return TRUE;

	type = check_packet_type(&packet);
	if (type == 0)
		return TRUE;

	server_id_option = dhcp_get_option(&packet, DHCP_SERVER_ID);
	if (server_id_option) {
		uint32_t server_nid = dhcp_get_unaligned(
					(uint32_t *) server_id_option);

		if (server_nid != dhcp_server->server_nip)
			return TRUE;
	}

	request_ip_option = dhcp_get_option(&packet, DHCP_REQUESTED_IP);
	if (request_ip_option)
		requested_nip = dhcp_get_unaligned(
					(uint32_t *) request_ip_option);

	lease = find_lease_by_mac(dhcp_server, packet.chaddr);

	switch (type) {
		case DHCPDISCOVER:
			debug(dhcp_server, "Received DISCOVER");

			send_offer(dhcp_server, &packet, lease, requested_nip);
		break;
		case DHCPREQUEST:
			debug(dhcp_server, "Received REQUEST NIP %d",
							requested_nip);
			if (requested_nip == 0) {
				requested_nip = packet.ciaddr;
				if (requested_nip == 0)
					break;
			}

			if (lease && requested_nip == lease->lease_nip) {
				debug(dhcp_server, "Sending ACK");
				send_ACK(dhcp_server, &packet,
						lease->lease_nip);
				break;
			}

			if (server_id_option || lease == NULL) {
				debug(dhcp_server, "Sending NAK");
				send_NAK(dhcp_server, &packet);
			}

		break;
		case DHCPDECLINE:
			debug(dhcp_server, "Received DECLINE");

			if (server_id_option == NULL)
				break;

			if (request_ip_option == NULL)
				break;

			if (lease == NULL)
				break;

			if (requested_nip == lease->lease_nip)
				remove_lease(dhcp_server, lease);

		break;
		case DHCPRELEASE:
			debug(dhcp_server, "Received RELEASE");

			if (server_id_option == NULL)
				break;

			if (lease == NULL)
				break;

			if (packet.ciaddr == lease->lease_nip)
				lease_set_expire(dhcp_server, lease,
								time(NULL));
		break;
		case DHCPINFORM:
			debug(dhcp_server, "Received INFORM");
			send_inform(dhcp_server, &packet);
		break;
	}

	return TRUE;
}
Example #2
0
File: server.c Project: rzr/connman
static gboolean listener_event(GIOChannel *channel, GIOCondition condition,
							gpointer user_data)
{
	GDHCPServer *dhcp_server = user_data;
	struct dhcp_packet packet;
	struct dhcp_lease *lease;
	uint32_t requested_nip = 0;
	uint8_t type, *server_id_option, *request_ip_option, *host_name;
	int re;

	GDHCPOptionType option_type;
	char *option_value;

	if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
		dhcp_server->listener_watch = 0;
		return FALSE;
	}

	re = dhcp_recv_l3_packet(&packet, dhcp_server->listener_sockfd);
	if (re < 0)
		return TRUE;

	type = check_packet_type(&packet);
	if (type == 0)
		return TRUE;

	server_id_option = dhcp_get_option(&packet, DHCP_SERVER_ID);
	if (server_id_option) {
		uint32_t server_nid = get_be32(server_id_option);

		if (server_nid != dhcp_server->server_nip)
			return TRUE;
	}

	request_ip_option = dhcp_get_option(&packet, DHCP_REQUESTED_IP);
	if (request_ip_option)
		requested_nip = get_be32(request_ip_option);

	lease = find_lease_by_mac(dhcp_server, packet.chaddr);

	switch (type) {
	case DHCPDISCOVER:
		debug(dhcp_server, "Received DISCOVER");

		send_offer(dhcp_server, &packet, lease, requested_nip);
		break;
	case DHCPREQUEST:
		debug(dhcp_server, "Received REQUEST NIP %d",
							requested_nip);
		if (requested_nip == 0) {
			requested_nip = packet.ciaddr;
			if (requested_nip == 0)
				break;
		}

		if (lease && requested_nip == lease->lease_nip) {
			debug(dhcp_server, "Sending ACK");
			host_name =
				dhcp_get_option(&packet,
					 DHCP_HOST_NAME);
			option_type =
				dhcp_get_code_type(DHCP_HOST_NAME);
			option_value =
				malloc_option_value_string(host_name,
					 option_type);

			send_ACK(dhcp_server, &packet,
				lease->lease_nip);

			if (dhcp_server->save_ack_lease_func)
				dhcp_server->save_ack_lease_func(
					option_value,
					lease->lease_mac,
					lease->lease_nip);

			g_free(option_value);

			break;
		}

		if (server_id_option || !lease) {
			debug(dhcp_server, "Sending NAK");
			send_NAK(dhcp_server, &packet);
		}

		break;
	case DHCPDECLINE:
		debug(dhcp_server, "Received DECLINE");

		if (!server_id_option)
			break;

		if (!request_ip_option)
			break;

		if (!lease)
			break;

		if (requested_nip == lease->lease_nip)
			remove_lease(dhcp_server, lease);

		break;
	case DHCPRELEASE:
		debug(dhcp_server, "Received RELEASE");

		if (!server_id_option)
			break;

		if (!lease)
			break;

		if (packet.ciaddr == lease->lease_nip)
			lease_set_expire(dhcp_server, lease,
					time(NULL));
		break;
	case DHCPINFORM:
		debug(dhcp_server, "Received INFORM");
		send_inform(dhcp_server, &packet);
		break;
	}

	return TRUE;
}
Example #3
0
void tskHandleRequests(void *pvParameters) {
	packet_t *requestPacket = NULL;

	packet_t *responsePacket = NULL;

	json_t *idObj;
	json_int_t id;


	char *errorString;
	strbuffer_t *errorBuffer;

	strbuffer_t *logMsg;

	portBASE_TYPE xStatus;
	while(1) {
		if(uxQueueMessagesWaiting(requestQueue) > 0) {
			xStatus = xQueueReceive( requestQueue, &requestPacket, (portTickType) QUEUE_RECEIVE_WAIT_TIMEOUT );
			if( (xStatus == pdPASS) && requestPacket) {

				if(check_packet_type(requestPacket, PKG_TYPE_INCOME_JSONRPC_REQUEST) != TRUE) {
					logger(LEVEL_ERR, "Wrong data packet from requestQueue. Deleting packet" );
					packet_destroy(&requestPacket);
					continue;

				}

				logMsg = strbuffer_new();
				strbuffer_append(logMsg, "Received new request: id=");
				strbuffer_append(logMsg, int_to_string(requestPacket->id));
				strbuffer_append(logMsg, " transport=");
				strbuffer_append(logMsg, int_to_string(requestPacket->transport));
				logger(LEVEL_INFO, logMsg->value);
				strbuffer_destroy(&logMsg);


				handle_request(requestPacket);
				responsePacket = requestPacket;
				if(responsePacket) {

					if(requestPacket->type == PKG_TYPE_OUTCOME_JSONRPC_NOTIFICATION) {
						logger(LEVEL_INFO, "Request was notification only. Destroying response");
						packet_destroy(&requestPacket);
						packet_destroy(&responsePacket);
						continue;
					}

					if(check_packet_type(requestPacket, PKG_TYPE_OUTCOME_JSONRPC_RESPONSE) != TRUE) {
						logger(LEVEL_ERR, "Wrong response packet. Deleting packet" );
						packet_destroy(&requestPacket);
						continue;
					}

					logMsg = strbuffer_new();
					strbuffer_append(logMsg, "Received response: id=");
					strbuffer_append(logMsg, int_to_string(responsePacket->id));
					strbuffer_append(logMsg, " transport=");
					strbuffer_append(logMsg, int_to_string(responsePacket->transport));
					logger(LEVEL_INFO, logMsg->value);
					strbuffer_destroy(&logMsg);


					logger(LEVEL_DEBUG, "creating json string from json object");

					strbuffer_t *stringData = strbuffer_new();

					char *jsonData = json_dumps(responsePacket->payload.jsonDoc, JSON_ENCODE_ANY );
					if(jsonData) {
						logger(LEVEL_DEBUG, "json string was created. Creating packet to send.");
						strbuffer_append(stringData, jsonData);

						logMsg = strbuffer_new();
						strbuffer_append(logMsg, "Sending new packet: packet_length=");
						strbuffer_append(logMsg, int_to_string(stringData->length));
						strbuffer_append(logMsg, " packet_transport=");
						strbuffer_append(logMsg, int_to_string(responsePacket->transport));
						logger(LEVEL_DEBUG, logMsg->value);
						strbuffer_destroy(&logMsg);



					} else {
						logMsg = strbuffer_new();
						strbuffer_append(logMsg, "Unable to create string from response json: id=");
						strbuffer_append(logMsg, int_to_string(responsePacket->id));
						strbuffer_append(logMsg, " transport=");
						strbuffer_append(logMsg, int_to_string(responsePacket->transport));
						logger(LEVEL_WARN, logMsg->value);
						strbuffer_destroy(&logMsg);

						errorString = format_jsonrpc_error(JSONRPC_SERVER_ERROR, MSG_JSONRPC_ERRORS.server_error, "internal server error", responsePacket->id);
						strbuffer_append(stringData, errorString);
					}

					vPortFree(jsonData);

					packet_lock(responsePacket);
					{
						json_decref(responsePacket->payload.jsonDoc);

						responsePacket->type = PKG_TYPE_OUTGOING_MESSAGE_STRING;
						responsePacket->payload.stringData = stringData;
					}
					packet_unlock(responsePacket);


					sendOutputMessage(responsePacket);

//					idObj = json_object_get(responseJson, "id");
//					id = json_integer_value(idObj);
//
//					json_t *transportObject = json_object_get(responseJson, "transport");
// 					json_int_t transport = json_integer_value(transportObject);
//
//					logger_format(LEVEL_INFO, "Received response. id = %d transport=%s", (int) id, transport_type_to_str((transport_type_t) transport));
//
//					xStatus = xQueueSendToBack( responseQueue, &responseJson, (portTickType) QUEUE_SEND_WAIT_TIMEOUT );
//					if( xStatus != pdPASS ){
//						char* idStr = json_dumps(json_object_get(requestPacket, "id"), JSON_ENCODE_ANY);
//						json_int_t transport = json_integer_value(json_object_get(requestPacket, "transport"));
//						json_object_del(requestPacket, "transport");
//						json_decref(requestJson);
//						// send using error reporting function
//						if(id && transport) {
//							report_error_to_sender(
//								(transport_type_t) transport,
//								MSG_JSONRPC_ERRORS.general_error_json,
//								JSONRPC_SERVER_ERROR,				/* <-- code */
//								MSG_JSONRPC_ERRORS.server_error,	/* <-- message */
//								MSG_MAINTASKS.tskAbstractReader.device_is_busy_timeout , /* <-- data */
//								idStr
//							);
//						}
//						if(idStr) vPortFree(idStr);
//						logger_format(LEVEL_INFO, "Unable to add response to queue. Request id = %d", (int) id );
//					} else {
//						logger(LEVEL_DEBUG, "Response was added to response queue");
//					}

				}
//				json_decref(requestPacket);
			}
		}
		taskYIELD();
	}

}