Ejemplo n.º 1
0
/**
 * Allocates a block of memory.  A direct replacement for malloc, but keeps track of items
 * allocated in a list, so that free can check that a item is being freed correctly and that
 * we can check that all memory is freed at shutdown.
 * @param file use the __FILE__ macro to indicate which file this item was allocated in
 * @param line use the __LINE__ macro to indicate which line this item was allocated at
 * @param size the size of the item to be allocated
 * @return pointer to the allocated item, or NULL if there was an error
 */
void* mymalloc(char* file, int line, size_t size)
{
	storageElement* s = NULL;
	size_t space = sizeof(storageElement);
	size_t filenamelen = strlen(file)+1;

	Thread_lock_mutex(heap_mutex);
	size = Heap_roundup(size);
	if ((s = malloc(sizeof(storageElement))) == NULL)
	{
		Log(LOG_ERROR, 13, errmsg);
		return NULL;
	}
	s->size = size; /* size without eyecatchers */
	if ((s->file = malloc(filenamelen)) == NULL)
	{
		Log(LOG_ERROR, 13, errmsg);
		free(s);
		return NULL;
	}
	space += filenamelen;
	strcpy(s->file, file);
	s->line = line;
	/* Add space for eyecatcher at each end */
	if ((s->ptr = malloc(size + 2*sizeof(int))) == NULL)
	{
		Log(LOG_ERROR, 13, errmsg);
		free(s->file);
		free(s);
		return NULL;
	}
	space += size + 2*sizeof(int);
	*(int*)(s->ptr) = eyecatcher; /* start eyecatcher */
	*(int*)(((char*)(s->ptr)) + (sizeof(int) + size)) = eyecatcher; /* end eyecatcher */
	Log(TRACE_MAX, -1, "Allocating %d bytes in heap at file %s line %d ptr %p\n", size, file, line, s->ptr);
	TreeAdd(&heap, s, space);
	state.current_size += size;
	if (state.current_size > state.max_size)
		state.max_size = state.current_size;
	Thread_unlock_mutex(heap_mutex);
	return ((int*)(s->ptr)) + 1;	/* skip start eyecatcher */
}
Ejemplo n.º 2
0
void ItemRecord::TreeAdd(ItemRecord *r, int c)
{ // dodanie rekordu do drzewa - ustalenie w której ga³êzi
    // zapisaæ w (iFlags) ile znaków jest zgodnych z nadrzêdnym, ¿eby nie sprawdzaæ wszystkich od
    // zera
    if ((cName[c] && r->cName[c]) ? cName[c] == r->cName[c] : false)
        TreeAdd(r, c + 1); // ustawiæ wg kolejnego znaku, chyba ¿e zero
    else if ((unsigned char)(cName[c]) < (unsigned char)(r->cName[c]))
    { // zero jest najmniejsze - doczepiamy jako (rNext)
        if (!rNext)
            rNext = r;
        else
            rNext->TreeAdd(r, 0); // doczepiæ do tej ga³êzi
    }
    else
    {
        if (!rPrev)
            rPrev = r;
        else
            rPrev->TreeAdd(r, 0); // doczepiæ do tej ga³êzi
    }
};
Ejemplo n.º 3
0
/**
 * Reallocates a block of memory.  A direct replacement for realloc, but keeps track of items
 * allocated in a list, so that free can check that a item is being freed correctly and that
 * we can check that all memory is freed at shutdown.
 * We have to remove the item from the tree, as the memory is in order and so it needs to
 * be reinserted in the correct place.
 * @param file use the __FILE__ macro to indicate which file this item was reallocated in
 * @param line use the __LINE__ macro to indicate which line this item was reallocated at
 * @param p pointer to the item to be reallocated
 * @param size the new size of the item
 * @return pointer to the allocated item, or NULL if there was an error
 */
void *myrealloc(char* file, int line, void* p, size_t size)
{
	void* rc = NULL;
	storageElement* s = NULL;

	Thread_lock_mutex(heap_mutex);
	s = TreeRemoveKey(&heap, ((int*)p)-1);
	if (s == NULL)
		Log(LOG_ERROR, 13, "Failed to reallocate heap item at file %s line %d", file, line);
	else
	{
		size_t space = sizeof(storageElement);
		size_t filenamelen = strlen(file)+1;

		checkEyecatchers(file, line, p, s->size);
		size = Heap_roundup(size);
		state.current_size += size - s->size;
		if (state.current_size > state.max_size)
			state.max_size = state.current_size;
		if ((s->ptr = realloc(s->ptr, size + 2*sizeof(int))) == NULL)
		{
			Log(LOG_ERROR, 13, errmsg);
			return NULL;
		}
		space += size + 2*sizeof(int) - s->size;
		*(int*)(s->ptr) = eyecatcher; /* start eyecatcher */
		*(int*)(((char*)(s->ptr)) + (sizeof(int) + size)) = eyecatcher; /* end eyecatcher */
		s->size = size;
		space -= strlen(s->file);
		s->file = realloc(s->file, filenamelen);
		space += filenamelen;
		strcpy(s->file, file);
		s->line = line;
		rc = s->ptr;
		TreeAdd(&heap, s, space);
	}
	Thread_unlock_mutex(heap_mutex);
	return (rc == NULL) ? NULL : ((int*)(rc)) + 1;	/* skip start eyecatcher */
}
Ejemplo n.º 4
0
void MQTTSProtocol_reconnect(char* ip_address, Clients* client)
{
	int port, rc;
	char *address = NULL;
	Clients* oldc = NULL;

	FUNC_ENTRY;
	oldc = TreeRemoveKeyIndex(bstate->disconnected_clients, client->clientID, 1);
	if (oldc == NULL)
		oldc = TreeRemoveKeyIndex(bstate->clients, client->clientID, 1);

	client->good = 1;
	client->ping_outstanding = 0;
	client->connect_state = 0;
	client->connected = 0;
	if (client->cleansession)
		client->msgID = 0;

	if (client->addr)
		free(client->addr);

	client->addr = malloc(strlen(ip_address));
	strcpy(client->addr, ip_address);

	address = MQTTProtocol_addressPort(ip_address, &port);
	rc = Socket_new_type(address, port, &(client->socket), SOCK_DGRAM);
	if (rc == EINPROGRESS || rc == EWOULDBLOCK)
		client->connect_state = 1; /* UDP connect called - improbable, but possible on obscure platforms */
	else if (rc == 0)
	{
		client->connect_state = 2; // TCP connect completed, in which case send the MQTT connect packet
		MQTTSPacket_send_connect(client);
		time(&(client->lastContact));
	}
	TreeAdd(bstate->clients, client, sizeof(Clients) + strlen(client->clientID)+1 + 3*sizeof(List));
	FUNC_EXIT;
}
Ejemplo n.º 5
0
int test(int limit)
{
	int i, *ip, *todelete;
	Node* current = NULL;
	Tree* t = TreeInitialize(TreeIntCompare);
	int rc = 0;

	printf("Tree initialized\n");

	srand(time(NULL));

	ip = malloc(sizeof(int));
	*ip = 2;
	TreeAdd(t, (void*)ip, sizeof(int));

	check(t);

	i = 2;
	void* result = TreeRemove(t, (void*)&i);
	if (result)
		free(result);

	int actual[limit];
	for (i = 0; i < limit; i++)
	{
		void* replaced = NULL;

		ip = malloc(sizeof(int));
		*ip = rand();
		replaced = TreeAdd(t, (void*)ip, sizeof(int));
		if (replaced) /* duplicate */
		{
			free(replaced);
			actual[i] = -1;
		}
		else
			actual[i] = *ip;
		if (i==5)
			todelete = ip;
		printf("Tree element added %d\n",  *ip);
		if (1 % 1000 == 0)
		{
			rc = check(t);
			printf("%d elements, check result %d\n", i+1, rc);
			if (rc != 0)
				return 88;
		}
	}

	check(t);

	for (i = 0; i < limit; i++)
	{
		int parm = actual[i];

		if (parm == -1)
			continue;

		Node* found = TreeFind(t, (void*)&parm);
		if (found)
			printf("Tree find %d %d\n", parm, *(int*)(found->content));
		else
		{
			printf("%d not found\n", parm);
			traverse(t, parm);
			return -2;
		}
	}

	check(t);

	for (i = limit -1; i >= 0; i--)
	{
		int parm = actual[i];
		void *found;

		if (parm == -1) /* skip duplicate */
			continue;

		found = TreeRemove(t, (void*)&parm);
		if (found)
		{
			printf("%d Tree remove %d %d\n", i, parm, *(int*)(found));
			free(found);
		}
		else
		{
			int count = 0;
			printf("%d %d not found\n", i, parm);
			traverse(t, parm);
			for (i = 0; i < limit; i++)
				if (actual[i] == parm)
					++count;
			printf("%d occurs %d times\n", parm, count);
			return -2;
		}
		if (i % 1000 == 0)
		{
			rc = check(t);
			printf("%d elements, check result %d\n", i+1, rc);
			if (rc != 0)
				return 88;
		}
	}
	printf("finished\n");
	return 0;
}
Ejemplo n.º 6
0
int MQTTSProtocol_handleConnects(void* pack, int sock, char* clientAddr, Clients* client, uint8_t* wirelessNodeId , uint8_t wirelessNodeIdLen)
{
	MQTTS_Connect* connect = (MQTTS_Connect*)pack;
	Listener* list = NULL;
	int terminate = 0;
	Node* elem = NULL;
	int rc = 0;
	int existingClient = 0;

	FUNC_ENTRY;
	Log(LOG_PROTOCOL, 39, NULL, sock, clientAddr, client ? client->clientID : "", connect->flags.cleanSession);

	if (bstate->clientid_prefixes->count > 0 &&
		!ListFindItem(bstate->clientid_prefixes, connect->clientID, clientPrefixCompare))
	{
		Log(LOG_WARNING, 31, NULL, connect->clientID);
		terminate = 1;
	}
	else
	{
		list = Socket_getParentListener(sock);
		if (list->max_connections > -1 &&
				list->connections->count > list->max_connections)
		{
			/* TODO: why is this commented out? delete if not needed
			//MQTTPacket_send_connack(3, sock);
			*/
			Log(LOG_WARNING, 141, NULL, connect->clientID, list->max_connections, list->port);
			terminate = 1;

		}
		else if (connect->protocolID != 1)
		{
			Log(LOG_WARNING, 32, NULL, "MQTT-S", connect->protocolID);
			/* TODO: why is this commented out? delete if not needed
			//MQTTPacket_send_connack(1, sock);
			 */
			terminate = 1;
		}
	}

	if (terminate)
	{
		/*TODO: process the terminate*/
		MQTTSPacket_free_packet(pack);
		goto exit;
	}

	if (client != NULL && !strcmp(client->clientID, connect->clientID))
	{
		/* Connect for a new client id on a used addr
		 * TODO: clean out 'old' Client (that may be 'connected')
		 */
	}

	elem = TreeFindIndex(bstate->mqtts_clients, connect->clientID, 1);
	if (elem == NULL)
	{
		client = TreeRemoveKey(bstate->disconnected_mqtts_clients, connect->clientID);
		if (client == NULL) /* this is a totally new connection */
		{
			/* Brand new client connection */
			int i;
		
			client = malloc(sizeof(Clients));
			memset(client, '\0', sizeof(Clients));
			client->protocol = PROTOCOL_MQTTS;
			client->outboundMsgs = ListInitialize();
			client->inboundMsgs = ListInitialize();
			for (i = 0; i < PRIORITY_MAX; ++i)
				client->queuedMsgs[i] = ListInitialize();
			client->registrations = ListInitialize();
			client->noLocal = 0; /* (connect->version == PRIVATE_PROTOCOL_VERSION) ? 1 : 0; */
			client->clientID = connect->clientID;
			connect->clientID = NULL; /* don't want to free this space as it is being used in the clients tree below */
			// Set Wireless Node ID if exists
			if ( wirelessNodeId == NULL)
			{
				client->wirelessNodeId = NULL ;
				client->wirelessNodeIdLen = 0 ;
			}
			else
			{
				client->wirelessNodeId = malloc((sizeof(uint8_t) * wirelessNodeIdLen)) ;
				memcpy( client->wirelessNodeId , wirelessNodeId , sizeof(uint8_t) * wirelessNodeIdLen) ;
				client->wirelessNodeIdLen = wirelessNodeIdLen ;
			}
		} // // client == NULL
		else /* there is an existing disconnected client */
		{
			/* Reconnect of a disconnected client */
			free(client->addr);
			client->connect_state = 0;
			client->connected = 0; /* Do not connect until we know the connack has been sent */

			// Delete Wireless Node ID if exists in existing client
			if ( wirelessNodeId == NULL)
			{
				if ( client->wirelessNodeId != NULL)
					free( client->wirelessNodeId )  ;
				client->wirelessNodeId = NULL ;
				client->wirelessNodeIdLen = 0 ;
			}
			else
			// Replace existing Wireless Node ID with value from current connect packet
			{
				if ( client->wirelessNodeId != NULL)
					free ( client->wirelessNodeId )  ;
				client->wirelessNodeId = malloc((sizeof(uint8_t) * wirelessNodeIdLen)) ;
				memcpy( client->wirelessNodeId , wirelessNodeId , sizeof(uint8_t) * wirelessNodeIdLen) ;
				client->wirelessNodeIdLen = wirelessNodeIdLen ;
			}
		} // client != NULL
		client->good = 1; /* good is set to 0 in disconnect, so we need to reset it here */
		client->keepAliveInterval = connect->keepAlive;
		client->cleansession = connect->flags.cleanSession;
		client->socket = sock;
		client->addr = malloc(strlen(clientAddr)+1);
		strcpy(client->addr, clientAddr);
		TreeAdd(bstate->mqtts_clients, client, sizeof(Clients) + strlen(client->clientID)+1 + 3*sizeof(List));

		if (client->cleansession)
			MQTTProtocol_removeAllSubscriptions(client->clientID); /* clear any persistent subscriptions */

		if (connect->flags.will)
		{
			client->connect_state = 1;
			rc = MQTTSPacket_send_willTopicReq(client);
		}
		else
		{
			client->connected = 1;
			rc = MQTTSPacket_send_connack(client, 0); /* send response */
		}
	}
	else
	{
		/* Reconnect of a connected client */
		client = (Clients*)(elem->content);
		if (client->connected)
		{
			Log(LOG_INFO, 34, NULL, connect->clientID, clientAddr);
			if (client->socket != sock)
				Socket_close(client->socket);
		}
		client->socket = sock;
		client->connected = 0; /* Do not connect until we know the connack has been sent */
		client->connect_state = 0;

		// Delete Wireless Node ID if exists in existing client
		if ( wirelessNodeId == NULL)
		{
			if ( client->wirelessNodeId != NULL)
				free( client->wirelessNodeId )  ;
			client->wirelessNodeId = NULL ;
			client->wirelessNodeIdLen = 0 ;
		}
		else
		// Replace existing Wireless Node ID with value from current connect packet
		{
			if ( client->wirelessNodeId != NULL)
				free ( client->wirelessNodeId )  ;
			client->wirelessNodeId = malloc((sizeof(uint8_t) * wirelessNodeIdLen)) ;
			memcpy( client->wirelessNodeId , wirelessNodeId , sizeof(uint8_t) * wirelessNodeIdLen) ;
			client->wirelessNodeIdLen = wirelessNodeIdLen ;
		}

		client->good = 1;
		if (client->addr != NULL)
			free(client->addr);
		client->addr = malloc(strlen(clientAddr)+1);
		strcpy(client->addr, clientAddr);

		client->cleansession = connect->flags.cleanSession;
		if (client->cleansession)
		{
			int i;
			MQTTProtocol_removeAllSubscriptions(client->clientID);
			/* empty pending message lists */
			MQTTProtocol_emptyMessageList(client->outboundMsgs);
			MQTTProtocol_emptyMessageList(client->inboundMsgs);
			for (i = 0; i < PRIORITY_MAX; ++i)
				MQTTProtocol_emptyMessageList(client->queuedMsgs[i]);
			MQTTProtocol_clearWill(client);
		}
		/* registrations are always cleared */
		MQTTSProtocol_emptyRegistrationList(client->registrations);
		
		/* have to remove and re-add client so it is in the right order for new socket */
		if (client->socket != sock)
		{
			TreeRemoveNodeIndex(bstate->mqtts_clients, elem, 1);
			TreeRemoveKeyIndex(bstate->mqtts_clients, &client->socket, 0);
			client->socket = sock;
			TreeAdd(bstate->mqtts_clients, client, sizeof(Clients) + strlen(client->clientID)+1 + 3*sizeof(List));
		}

		client->keepAliveInterval = connect->keepAlive;
		client->pendingRegistration = NULL;
#if !defined(NO_BRIDGE)
		client->pendingSubscription = NULL;
#endif

		if (connect->flags.will)
		{
			client->connect_state = 1;
			rc = MQTTSPacket_send_willTopicReq(client);
		}
		else
		{
			client->connected = 1;
			rc = MQTTSPacket_send_connack(client,0); /* send response */
		}
	}
	
	if (existingClient)
		MQTTProtocol_processQueued(client);

	Log(LOG_INFO, 0, "Client connected to udp port %d from %s (%s)", list->port, client->clientID, clientAddr);

	MQTTSPacket_free_packet(pack);
	time( &(client->lastContact) );
exit:
	FUNC_EXIT_RC(rc);
	return rc;
}
Ejemplo n.º 7
0
/**
 * Create the server socket in multi-listener mode.
 * @param list pointer to a listener structure
 * @return completion code
 */
int Socket_addServerSocket(Listener* list)
{
	int flag = 1;
	int rc = SOCKET_ERROR;
	int ipv4 = 1; /* yes we can drop down to ipv4 */

	FUNC_ENTRY;
	if (!list->address || strcmp(list->address, "INADDR_ANY") == 0)
	{
		struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
		list->addr.sin_addr.s_addr = htonl(INADDR_ANY);
		list->addr6.sin6_addr = in6addr_any;
	}
	else
	{
		if (list->address[0] == '[')
		{
			int changed = ipv6_format(list->address);
#if defined(WIN32)
			/*wchar_t buf[(INET6_ADDRSTRLEN+1)*2];
			int buflen = sizeof(list->addr6);
			mbstowcs(buf, &list->address[1], sizeof(buf));
			rc = WSAStringToAddress(buf, AF_INET6, NULL, (struct sockaddr*)&list->addr6, &buflen);*/
			rc = win_inet_pton(AF_INET6, &list->address[1], &(list->addr6.sin6_addr));
#else
			rc = inet_pton(AF_INET6, &list->address[1], &(list->addr6.sin6_addr));
#endif
			ipv4 = 0;
			if (changed)
				(list->address)[changed] = ']';
		}
		else
		{
#if defined(WIN32)
			/*wchar_t buf[(INET6_ADDRSTRLEN+1)*2];
			int buflen = sizeof(list->addr);
			mbstowcs(buf, list->address, sizeof(buf));
			rc = WSAStringToAddress(buf, AF_INET, NULL, (struct sockaddr*)&list->addr, &buflen);*/
			rc = win_inet_pton(AF_INET, list->address, &(list->addr.sin_addr.s_addr));
#else
			rc = inet_pton(AF_INET, list->address, &(list->addr.sin_addr.s_addr));
#endif
			list->ipv6 = 0;
		}
#if defined(WIN32)
		if (rc != 0)
#else
		if (rc != 1)
#endif
		{
			Log(LOG_WARNING, 67, NULL, list->address);
			rc = -1;
			goto exit;
		}
	}
	list->socket = -1;
	if (list->protocol == PROTOCOL_MQTT)
	{
		if (list->ipv6)
			list->socket = socket(AF_INET6, SOCK_STREAM, 0);
		if (list->socket < 0 && ipv4)
		{
			list->socket = socket(AF_INET, SOCK_STREAM, 0);
			list->ipv6 = 0;
		}
	}
#if defined(MQTTS)
	else if (list->protocol == PROTOCOL_MQTTS)
	{
		if (list->ipv6)
			list->socket = socket(AF_INET6, SOCK_DGRAM, 0);
		if (list->socket < 0 && ipv4)
		{
			list->socket = socket(AF_INET, SOCK_DGRAM, 0);
			list->ipv6 = 0;
		}
	}
#endif
	Log(TRACE_MAX, 6, NULL, FD_SETSIZE);
	if (list->socket < 0)
	{
		Socket_error("socket", list->socket);
		Log(LOG_WARNING, 77, NULL);
		rc = list->socket;
		goto exit;
	}

#if !defined(WIN32)
	if (setsockopt(list->socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&flag, sizeof(int)) != 0)
		Log(LOG_WARNING, 109, NULL, list->port);
#endif
	if (list->ipv6)
	{
		list->addr6.sin6_family = AF_INET6;
		list->addr6.sin6_port = htons(list->port);
		rc = bind(list->socket, (struct sockaddr *)&(list->addr6), sizeof(list->addr6));
	}
	else
	{
		list->addr.sin_family = AF_INET;
		list->addr.sin_port = htons(list->port);
		memset(list->addr.sin_zero, 0, sizeof(list->addr.sin_zero));
		rc = bind(list->socket, (struct sockaddr *)&(list->addr), sizeof(list->addr));
	}
	if (rc == SOCKET_ERROR)
	{
		Socket_error("bind", list->socket);
		Log(LOG_WARNING, 78, NULL, list->port);
		goto exit;
	}

	/* Only listen if this is mqtt/tcp */
	if (list->protocol == PROTOCOL_MQTT &&
			listen(list->socket, SOMAXCONN) == SOCKET_ERROR) /* second parm is max no of connections */
	{
		Socket_error("listen", list->socket);
		Log(LOG_WARNING, 79, NULL, list->port);
		goto exit;
	}

	if (Socket_setnonblocking(list->socket) == SOCKET_ERROR)
	{
		Socket_error("setnonblocking", list->socket);
		goto exit;
	}

#if defined(MQTTS)
	/* If mqtts/udp, add to the list of clientsds to test for reading */
	if (list->protocol == PROTOCOL_MQTTS)
	{
		ListElement* current = NULL;
		int loopback = list->loopback;

#if !defined(USE_POLL)
		int* pnewSd = (int*)malloc(sizeof(list->socket));

		*pnewSd = list->socket;
		ListAppend(s.clientsds, pnewSd, sizeof(list->socket));
#endif
		Log(LOG_INFO, 300, NULL, list->port);

		if (setsockopt(list->socket, IPPROTO_IP, IP_MULTICAST_LOOP, (const char*)&loopback, sizeof(loopback)) == SOCKET_ERROR)
			Socket_error("set listener IP_MULTICAST_LOOP", list->socket);

		/* join any multicast groups */
		while (ListNextElement(list->multicast_groups, &current))
			Socket_joinMulticastGroup(list->socket, list->ipv6, (char*)(current->content));
	}
	else
#endif
		Log(LOG_INFO, 14, NULL, list->port);

#if defined(USE_POLL)
	/* add new socket to the epoll descriptor with epoll_ctl */
	struct socket_info* si = malloc(sizeof(struct socket_info));
	si->listener = list;
	si->fd = list->socket;
	si->connect_pending = 0;
	si->event.events = EPOLLIN;
	si->event.data.ptr = si;
	TreeAdd(s.fds_tree, si, sizeof(struct socket_info));
	if (epoll_ctl(s.epoll_fds, EPOLL_CTL_ADD, list->socket, &si->event) != 0)
		Socket_error("epoll_ctl add", list->socket);
#else
	FD_SET((u_int)list->socket, &(s.rset));         /* Add the current socket descriptor */
	s.maxfdp1 = max(s.maxfdp1+1, list->socket+1);

	memcpy((void*)&(s.rset_saved), (void*)&(s.rset), sizeof(s.rset_saved));
#endif

	rc = 0;
exit:
	FUNC_EXIT_RC(rc);
	return rc;
}
Ejemplo n.º 8
0
bool FolderAdd(MessageTreeItem *pItem)
{
   return TreeAdd(g_pFolderTree, g_pFolderList, pItem, &g_lFolderMaxID);
}
Ejemplo n.º 9
0
/*
 * Process Response files on the command line
 * Returns true if it allocated a new argv array that must be freed later
 */
void ConsoleArgs::ProcessResponseArgs()
{
    HRESULT hr;
    b_tree *response_files = NULL;

    WCHAR   szFilename[MAX_PATH];
    WCAllocBuffer textBuffer;

    for (WStrList * listCurArg = m_listArgs;
        listCurArg != NULL && !m_output->HadFatalError();
        listCurArg = listCurArg->next)
    {
        WCHAR  * szArg = listCurArg->arg;

        // Skip everything except Response files
        if (szArg == NULL || szArg[0] != '@')
            continue;

        if (wcslen(szArg) == 1) {
            m_output->ShowErrorIdString( ERR_NoFileSpec, ERROR_ERROR, szArg);
            goto CONTINUE;
        }

        // Check for duplicates
        if (!GetFullFileName( RemoveQuotes(WCBuffer::CreateFrom(&szArg[1])), szFilename, false))
            continue;

        hr = TreeAdd(&response_files, szFilename);
        if (hr == E_OUTOFMEMORY) {
            m_output->ShowErrorId(FTL_NoMemory, ERROR_FATAL);
            goto CONTINUE;
        } else if (hr == S_FALSE) {
            m_output->ShowErrorIdString(ERR_DuplicateResponseFile, ERROR_ERROR, szFilename);
            goto CONTINUE;
        }

        FileType fileType;
        textBuffer.Clear();
        if (FAILED(hr = ReadTextFile(szFilename, NULL, textBuffer, &fileType)) || hr == S_FALSE)
        {
            if (hr == E_OUTOFMEMORY) {
                m_output->ShowErrorId(FTL_NoMemory, ERROR_FATAL);
            } else if (FAILED(hr)) {
                if (fileType == ftBinary)
                    m_output->ShowErrorIdString(ERR_BinaryFile, ERROR_ERROR, szFilename);
                else
                    m_output->ShowErrorIdString(ERR_OpenResponseFile, ERROR_ERROR, szFilename, m_output->ErrorHR(hr));
            }
            goto CONTINUE;
        }


        TextToArgs( textBuffer, &listCurArg->next);

CONTINUE: // remove the response file argument, and continue to the next.
        listCurArg->arg = NULL;
        VSFree(szArg);
    }

    CleanupTree(response_files);
}
Ejemplo n.º 10
0
/**
 * Process an incoming connect packet for a socket
 * @param pack pointer to the connect packet
 * @param sock the socket on which the packet was received
 * @return completion code
 */
int MQTTProtocol_handleConnects(void* pack, int sock, Clients* client)
{
	Connect* connect = (Connect*)pack;
	Node* elem = NULL;
	int terminate = 0;
	int rc = TCPSOCKET_COMPLETE;
#if !defined(SINGLE_LISTENER)
	Listener* listener = Socket_getParentListener(sock);
#endif

	FUNC_ENTRY;
	Log(LOG_PROTOCOL, 26, NULL, sock, connect->clientID);/*
			connect->Protocol, connect->flags.bits.cleanstart, connect->keepAliveTimer,
			connect->version, connect->username, connect->password);*/
	Socket_removeNew(sock);		
			
	if (bstate->state != BROKER_RUNNING)
		terminate = 1; /* don't accept new connection requests when we are shutting down */
	/* Now check the version.  If we don't recognize it we will not have parsed the packet,
	 * so nothing else in the packet structure will have been filled in.
	 */
	else if (!MQTTPacket_checkVersion(pack))
	{
		Log(LOG_WARNING, 32, NULL, connect->Protocol, connect->version);
		rc = MQTTPacket_send_connack(CONNACK_UNACCEPTABLE_PROTOCOL_VERSION, sock, Socket_getpeer(sock)); /* send response */
		terminate = 1;
	}
	else if (connect->clientID[0] == '\0' || (connect->version == 3 && strlen(connect->clientID) > 23))
	{
		rc = MQTTPacket_send_connack(CONNACK_IDENTIFIER_REJECTED, sock, Socket_getpeer(sock)); /* send response */
		terminate = 1;
	}
	else if (bstate->password_file != NULL)
	{
		if (connect->flags.bits.username && connect->flags.bits.password &&
				(Users_authenticate(connect->username, connect->password) == false))
		{
			Log(LOG_WARNING, 31, NULL, connect->clientID);
			rc = MQTTPacket_send_connack(CONNACK_BAD_USERNAME_OR_PASSWORD, sock, connect->clientID); /* send bad user/pass response */
			terminate = 1;
		}
		else if ((!connect->flags.bits.username || !connect->flags.bits.password) && !bstate->allow_anonymous)
		{
			Log(LOG_WARNING, 31, NULL, connect->clientID);
			rc = MQTTPacket_send_connack(CONNACK_BROKER_UNAVAILABLE, sock, connect->clientID); /* send broker unavailable response */
			terminate = 1;
		}
	}

	if (terminate)
		;
	else if (bstate->clientid_prefixes->count > 0 &&
		!ListFindItem(bstate->clientid_prefixes, connect->clientID, clientPrefixCompare))
	{
		Log(LOG_WARNING, 31, NULL, connect->clientID);
		terminate = 1;
	}
	else
	{
#if !defined(SINGLE_LISTENER)
		if (listener->max_connections > -1 &&
				listener->connections->count > listener->max_connections)
		{
			Log(LOG_WARNING, 141, NULL, connect->clientID, listener->max_connections, listener->port);
#else
		if (bstate->max_connections > -1 &&
			MQTTProtocol_getNoConnectedClients() >= bstate->max_connections)
		{
			Log(LOG_WARNING, 141, NULL, connect->clientID, bstate->max_connections, bstate->port);
#endif
			rc = MQTTPacket_send_connack(CONNACK_BROKER_UNAVAILABLE, sock, connect->clientID); /* send response */
			terminate = 1;
		}
	}

	if (terminate)
	{
		MQTTPacket_freeConnect(connect);
		Socket_close(sock);
		rc = TCPSOCKET_COMPLETE;
		goto exit;
	}

	if (bstate->connection_messages)
		Log(LOG_INFO,
#if !defined(SINGLE_LISTENER)
			33, NULL, listener->port, connect->clientID, Socket_getpeer(sock));
#else
			33, NULL, bstate->port, connect->clientID, Socket_getpeer(sock));
#endif

	elem = TreeFindIndex(bstate->clients, connect->clientID, 1);
	if (elem == NULL)
	{
		client = TreeRemoveKey(bstate->disconnected_clients, connect->clientID);
		if (client == NULL)
		{
			int i;
			char* tmpAddr = NULL;

			client = malloc(sizeof(Clients));
			memset(client, '\0', sizeof(Clients));
			tmpAddr = Socket_getpeer(sock);
			client->addr = malloc(strlen(tmpAddr)+1);
			strcpy(client->addr, tmpAddr);
	#if defined(MQTTS)
			client->protocol = PROTOCOL_MQTT;
	#endif
			client->clientID = connect->clientID;
			client->outboundMsgs = ListInitialize();
			client->inboundMsgs = ListInitialize();
			for (i = 0; i < PRIORITY_MAX; ++i)
				client->queuedMsgs[i] = ListInitialize();
			connect->clientID = NULL; /* don't want to free this space as it is being used in the client structure */
		}
		client->socket = sock;
		TreeAdd(bstate->clients, client, sizeof(Clients) + strlen(client->clientID)+1 + 3*sizeof(List));
	}
	else
	{
		client = (Clients*)(elem->content);
		if (client->connected)
		{
			Log(LOG_INFO, 34, NULL, connect->clientID, Socket_getpeer(sock));
			if (client->socket != sock)
				Socket_close(client->socket);
		}

		if (connect->flags.bits.cleanstart)
		{
			int i;
			/* empty pending message lists */
			MQTTProtocol_emptyMessageList(client->outboundMsgs);
			MQTTProtocol_emptyMessageList(client->inboundMsgs);
			for (i = 0; i < PRIORITY_MAX; ++i)
				MQTTProtocol_emptyMessageList(client->queuedMsgs[i]);
			client->msgID = client->outbound = client->ping_outstanding = 0;
		}

		/* have to remove and re-add client so it is in the right order for new socket */
		if (client->socket != sock)
		{
			TreeRemoveNodeIndex(bstate->clients, elem, 1);
			TreeRemoveKeyIndex(bstate->clients, &client->socket, 0);
			client->socket = sock;
			TreeAdd(bstate->clients, client, sizeof(Clients) + strlen(client->clientID)+1 + 3*sizeof(List));
		}
	}

	client->good = client->connected = 1;
	client->cleansession = connect->flags.bits.cleanstart;
	client->keepAliveInterval = connect->keepAliveTimer;
	client->noLocal = (connect->version == PRIVATE_PROTOCOL_VERSION) ? 1 : 0;
	if (client->cleansession)
		MQTTProtocol_removeAllSubscriptions(client->clientID); /* clear any persistent subscriptions */
#if !defined(SINGLE_LISTENER)
	if (listener && listener->mount_point && connect->flags.bits.will)
	{
		char* temp = malloc(strlen(connect->willTopic) + strlen(listener->mount_point) + 1);
		strcpy(temp, listener->mount_point);
		strcat(temp, connect->willTopic);
		free(connect->willTopic);
		connect->willTopic = temp;
	}
#endif
#if defined(MQTTS)
	if (connect->flags.bits.will)
	{
		MQTTProtocol_setWillTopic(client, connect->willTopic,
									connect->flags.bits.willRetain, connect->flags.bits.willQoS);
		MQTTProtocol_setWillMsg(client, connect->willMsg);
		connect->willTopic = NULL;
		connect->willMsg = NULL;
	}
#else
	MQTTProtocol_setWill(connect, client);
#endif

	if (connect->flags.bits.username)
	{
		client->user = Users_get_user(connect->username);
	}

	rc = MQTTPacket_send_connack(CONNACK_CONNECTION_ACCEPTED, sock, client->clientID); /* send response */

	if (client->cleansession == 0)
	{
		ListElement* outcurrent = NULL;
		time_t now = 0;

		/* ensure that inflight messages are retried now by setting the last touched time
		 * to very old (0) before calling the retry function
		 */
		time(&(now));
		while (ListNextElement(client->outboundMsgs, &outcurrent))
		{
			Messages* m = (Messages*)(outcurrent->content);
			m->lastTouch = 0;
		}
		MQTTProtocol_retries(now, client);
		MQTTProtocol_processQueued(client);
	}
	time(&(client->lastContact));

	MQTTPacket_freeConnect(connect);

exit:
	FUNC_EXIT_RC(rc);
	return rc;
}


/**
 * Process an incoming ping request packet for a socket
 * @param pack pointer to the publish packet
 * @param sock the socket on which the packet was received
 * @return completion code
 */
int MQTTProtocol_handlePingreqs(void* pack, int sock, Clients* client)
{
	int rc = TCPSOCKET_COMPLETE;

	FUNC_ENTRY;
	Log(LOG_PROTOCOL, 3, NULL, sock, client->clientID);
	rc = MQTTPacket_send_pingresp(sock, client->clientID);
	FUNC_EXIT_RC(rc);
	return rc;
}
Ejemplo n.º 11
0
/**
 * Close any active session for a client and clean up.
 * @param client the client to clean up
 * @param send_will flag to indicate whether a will messsage should be sent if it has been set
 */
void MQTTProtocol_closeSession(Clients* client, int send_will)
{
	FUNC_ENTRY;
	client->good = 0;
	if (in_MQTTPacket_Factory == client->socket || client->closing)
		goto exit;
	client->closing = 1;
	if (client->socket > 0)
	{
		if (client->connected)
		{
			if (client->outbound && client->will)
			{
				Publish pub;
				pub.payload = "0";
				pub.payloadlen = 1;
				pub.topic = client->will->topic;
#if defined(MQTTS)
				if (client->protocol == PROTOCOL_MQTTS)
					MQTTSProtocol_startPublishCommon(client, &pub, 0,0,1);
				if (client->protocol == PROTOCOL_MQTTS_DTLS)
					MQTTSProtocol_startPublishCommon(client, &pub, 0,0,1);
					//TODO LW
				else
#endif
					MQTTPacket_send_publish(&pub, 0, 0, 1, client->socket, client->clientID);
				MQTTProtocol_sys_publish(client->will->topic, "0");
			}
#if defined(MQTTS)
			if (client->protocol == PROTOCOL_MQTTS_MULTICAST)
				;
			else if (client->protocol == PROTOCOL_MQTTS)
				MQTTSPacket_send_disconnect(client, 0);
			else if (client->protocol == PROTOCOL_MQTTS_DTLS)
				MQTTSPacket_send_disconnect(client, 0);
			else
#endif
			if (client->outbound)
				MQTTPacket_send_disconnect(client->socket, client->clientID);
		}

		if (ListFindItem(&(state.pending_writes), &(client->socket), intcompare))
		{
			pending_write* pw = (pending_write*)(state.pending_writes.current->content);
			MQTTProtocol_removePublication(pw->p);
			ListRemove(&(state.pending_writes), pw);
		}

#if defined(MQTTS)
		if (client->protocol == PROTOCOL_MQTT || client->outbound == 1)
		{
			if (client->protocol == PROTOCOL_MQTTS_MULTICAST)
				Socket_close_only(client->socket);
			else
#endif
				Socket_close(client->socket);
#if defined(MQTTS)
		}
#endif
	}
	if (client->connected || client->connect_state)
	{
		client->connected = 0;
		client->connect_state = 0;
	}
	if (client->outbound == 0 && client->will != NULL && send_will)
	{
		Publish publish;
		publish.payload = client->will->msg;
		publish.payloadlen = strlen(client->will->msg);
		publish.topic = client->will->topic;
		publish.header.bits.qos = client->will->qos;
		publish.header.bits.retain = client->will->retained;
		Protocol_processPublication(&publish, client->clientID);
	}
#if defined(MQTTS)
	if (client->protocol == PROTOCOL_MQTTS)
		MQTTSProtocol_emptyRegistrationList(client->registrations);
	else if (client->protocol == PROTOCOL_MQTTS_DTLS)
		MQTTSProtocol_emptyRegistrationList(client->registrations);
#endif
	if (client->cleansession)
	{
		if (client->outbound && ((BridgeConnections*)(client->bridge_context))->state != CONNECTION_DELETE)
		{ /* bridge outbound client structures are reused on reconnection */
			int i;
			MQTTProtocol_removeAllSubscriptions(client->clientID);
			MQTTProtocol_emptyMessageList(client->inboundMsgs);
			MQTTProtocol_emptyMessageList(client->outboundMsgs);
			for (i = 0; i < PRIORITY_MAX; ++i)
				MQTTProtocol_emptyMessageList(client->queuedMsgs[i]);
			client->msgID = 0;
		}
		else
		{
#if defined(MQTTS)
			if ((client->protocol == PROTOCOL_MQTTS && client->outbound == 0) || (client->protocol == PROTOCOL_MQTTS_DTLS && client->outbound == 0) || client->protocol == PROTOCOL_MQTTS_MULTICAST)
			{
				if (!TreeRemove(bstate->mqtts_clients, client) && !TreeRemove(bstate->disconnected_mqtts_clients, client))
					Log(LOG_ERROR, 39, NULL);
				else
					Log(TRACE_MAX, 2, NULL, client->clientID, client->socket);
			}
			else
			{
#endif
				if (!TreeRemove(bstate->clients, client) && !TreeRemove(bstate->disconnected_clients, client))
					Log(LOG_ERROR, 39, NULL);
				else
					Log(TRACE_MAX, 2, NULL, client->clientID, client->socket);
#if defined(MQTTS)
			}
#endif
			MQTTProtocol_freeClient(client);
		}
	}
	else
	{
		int i;
		for (i = 0; i < PRIORITY_MAX; ++i)
			MQTTProtocol_removeQoS0Messages(client->queuedMsgs[i]);
#if defined(MQTTS)
		if ((client->protocol == PROTOCOL_MQTTS && client->outbound == 0)||(client->protocol == PROTOCOL_MQTTS_DTLS && client->outbound == 0))
		{
			if (TreeRemove(bstate->mqtts_clients, client))
			{
				client->socket = 0;
				TreeAdd(bstate->disconnected_mqtts_clients, client, sizeof(Clients) + strlen(client->clientID)+1 + 3*sizeof(List));
			}
		}
		else
		{
#endif
		if (TreeRemove(bstate->clients, client))
		{
			client->socket = 0;
			TreeAdd(bstate->disconnected_clients, client, sizeof(Clients) + strlen(client->clientID)+1 + 3*sizeof(List));
		}
#if defined(MQTTS)
		}
#endif
    	client->closing = 0;
	}

exit:
	FUNC_EXIT;
}
Ejemplo n.º 12
0
Clients* MQTTSProtocol_create_multicast(char* ip_address, char* clientID, int loopback)
{ /* outgoing connection */
	int i, port, rc;
	char* addr;
	Clients* newc = NULL;
	char* intface = NULL;
	int ipv6 = 0;

	FUNC_ENTRY;
	newc = malloc(sizeof(Clients));
	memset(newc, '\0', sizeof(Clients));
	newc->clientID = clientID;
	newc->outbound = 1;
	newc->good = 1;
	newc->connected = 1;
	newc->outboundMsgs = ListInitialize();
	newc->inboundMsgs = ListInitialize();
	for (i = 0; i < PRIORITY_MAX; ++i)
		newc->queuedMsgs[i] = ListInitialize();
	newc->registrations = ListInitialize();

	newc->protocol = PROTOCOL_MQTTS_MULTICAST;

	/* if there is a space in the ip_address string, it means we have address plus interface specified */
	if ((intface = strchr(ip_address, ' ')) != NULL)
	{
		*intface = '\0';
		++intface;
	}

	addr = MQTTProtocol_addressPort(ip_address, &port);

	newc->addr = malloc(strlen(ip_address) + 1);
	strcpy(newc->addr, ip_address);

	ipv6 = (newc->addr[0] == '[');

	rc = Socket_new_udp(&(newc->socket), ipv6);

	if (setsockopt(newc->socket, IPPROTO_IP, IP_MULTICAST_LOOP, (const char*)&loopback, sizeof(loopback)) == SOCKET_ERROR)
		Socket_error("set bridge IP_MULTICAST_LOOP", newc->socket);

	if (intface)
	{
		if (ipv6)
		{
			int index = 0;

			if ((index = if_nametoindex(intface)) == 0)
				Socket_error("get interface index", newc->socket);
			else if (setsockopt(newc->socket, IPPROTO_IPV6, IPV6_MULTICAST_IF, (const char*)&index, sizeof(index)) == SOCKET_ERROR)
				Socket_error("set bridge IP_MULTICAST_IF", newc->socket);
		}
		else
		{
			struct in_addr interface_addr;
#if defined(WIN32)
			if ((rc = win_inet_pton(AF_INET, intface, &interface_addr)) == SOCKET_ERROR)
				Socket_error("WSAStringToAddress interface", newc->socket);
			else
			{
#else
			/* get address of the interface */
			struct ifreq ifreq;

			strncpy(ifreq.ifr_name, intface, IFNAMSIZ);
			if (ioctl(newc->socket, SIOCGIFADDR, &ifreq) == SOCKET_ERROR)
				Socket_error("get interface address", newc->socket);
			else
			{
				memcpy(&interface_addr, &((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr, sizeof(struct in_addr));
#endif
				if (setsockopt(newc->socket, IPPROTO_IP, IP_MULTICAST_IF, &interface_addr, sizeof(interface_addr)) == SOCKET_ERROR)
					Socket_error("set bridge IP_MULTICAST_IF", newc->socket);
			}
		}
	}

	TreeAdd(bstate->disconnected_mqtts_clients, newc, sizeof(Clients) + strlen(newc->clientID)+1 + 3*sizeof(List));

	FUNC_EXIT;
	return newc;
}


Clients* MQTTSProtocol_connect(char* ip_address, char* clientID, int cleansession, int try_private, int keepalive, willMessages* willMessage)
{ /* outgoing connection */
	int rc, port;
	char* addr;
	Clients* newc = NULL;

	FUNC_ENTRY;
	newc = TreeRemoveKeyIndex(bstate->disconnected_clients, clientID, 1); /* must be a dummy client */
	if (newc == NULL)
		newc = TreeRemoveKeyIndex(bstate->clients, clientID, 1);
	if (newc)
	{
		free(clientID);
		newc->connected = newc->ping_outstanding = newc->connect_state = newc->msgID = newc->discardedMsgs = 0;
	}
	else
	{
		int i;
		newc = malloc(sizeof(Clients));
		memset(newc, '\0', sizeof(Clients));
		newc->outboundMsgs = ListInitialize();
		newc->inboundMsgs = ListInitialize();
		for (i = 0; i < PRIORITY_MAX; ++i)
			newc->queuedMsgs[i] = ListInitialize();
		newc->clientID = clientID;
	}
	newc->cleansession = cleansession;
	newc->outbound = newc->good = 1;
	newc->keepAliveInterval = keepalive;
	newc->registrations = ListInitialize();
	newc->will = willMessage;
	newc->noLocal = try_private; /* try private connection first */
	time(&(newc->lastContact));
	newc->pendingRegistration = NULL;
	newc->protocol = PROTOCOL_MQTTS;

	addr = MQTTProtocol_addressPort(ip_address, &port);

	newc->addr = malloc(strlen(ip_address));
	strcpy(newc->addr, ip_address);

	rc = Socket_new_type(addr, port, &(newc->socket), SOCK_DGRAM);

	if (rc == EINPROGRESS || rc == EWOULDBLOCK)
		newc->connect_state = 1; /* UDP connect called - improbable, but possible on obscure platforms */
	else if (rc == 0)
	{
		newc->connect_state = 2;
		rc = MQTTSPacket_send_connect(newc);
	}
	TreeAdd(bstate->clients, newc, sizeof(Clients) + strlen(newc->clientID)+1 + 3*sizeof(List));

	FUNC_EXIT;
	return newc;
}