mirror of
				https://github.com/berlin-open-wireless-lab/DAWN.git
				synced 2025-03-09 15:40:12 +00:00 
			
		
		
		
	- Merge encoded / plain messge handling to ensure fixes land in both - Fix some potential resource leaks spotted by Coverity [cleanup commit message] [fix merge conflicts] Signed-off-by: Nick Hainke <vincent@systemli.org>
		
			
				
	
	
		
			198 lines
		
	
	
	
		
			5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			198 lines
		
	
	
	
		
			5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #include <stdio.h>
 | |
| #include <stdlib.h>
 | |
| #include <string.h>
 | |
| #include <libubox/blobmsg_json.h>
 | |
| 
 | |
| #include "utils.h"
 | |
| #include "memory_utils.h"
 | |
| #include "multicastsocket.h"
 | |
| #include "broadcastsocket.h"
 | |
| #include "msghandler.h"
 | |
| #include "crypto.h"
 | |
| #include "datastorage.h"
 | |
| #include "networksocket.h"
 | |
| 
 | |
| 
 | |
| /* Network Defines */
 | |
| #define MAX_RECV_STRING 2048
 | |
| 
 | |
| /* Network Attributes */
 | |
| static int sock;
 | |
| static struct sockaddr_in addr;
 | |
| static const char *ip;
 | |
| static unsigned short port;
 | |
| static char recv_string[MAX_RECV_STRING + 1];
 | |
| static int recv_string_len;
 | |
| static int multicast_socket;
 | |
| 
 | |
| static pthread_mutex_t send_mutex;
 | |
| 
 | |
| void *receive_msg(void *args);
 | |
| 
 | |
| void *receive_msg_enc(void *args);
 | |
| 
 | |
| int init_socket_runopts(const char *_ip, int _port, int _multicast_socket) {
 | |
| 
 | |
|     port = _port;
 | |
|     ip = _ip;
 | |
|     multicast_socket = _multicast_socket;
 | |
| 
 | |
|     if (multicast_socket) {
 | |
|         dawnlog_info("Settingup multicastsocket!\n");
 | |
|         sock = setup_multicast_socket(ip, port, &addr);
 | |
|     } else {
 | |
|         sock = setup_broadcast_socket(ip, port, &addr);
 | |
|     }
 | |
| 
 | |
|     pthread_t sniffer_thread;
 | |
|     if (network_config.use_symm_enc) {
 | |
|         if (pthread_create(&sniffer_thread, NULL, receive_msg_enc, NULL)) {
 | |
|             dawnlog_error("Could not create receiving thread!\n");
 | |
|             return -1;
 | |
|         }
 | |
|     } else {
 | |
|         if (pthread_create(&sniffer_thread, NULL, receive_msg, NULL)) {
 | |
|             dawnlog_error("Could not create receiving thread!\n");
 | |
|             return -1;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     dawnlog_info("Connected to %s:%d\n", ip, port);
 | |
| 
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| // TODO: Will all messages arrive in a single read? Borrow looping partial read from tcpsocket.c?
 | |
| static void* receive_msg_inner(void* args, bool is_enc) {
 | |
| 
 | |
|     while (1) {
 | |
|         recv_string_len = recvfrom(sock, recv_string, MAX_RECV_STRING, 0, NULL, 0);
 | |
| 
 | |
|         //FIXME: Next few lines look a bit mangled, with odd strlen() tests, etc...
 | |
|         if (recv_string_len < 0) {
 | |
|             dawnlog_error("Could not receive message!");
 | |
|             continue;
 | |
|         }
 | |
| 
 | |
|         if (recv_string_len == 0) {
 | |
|             return 0;
 | |
|         }
 | |
| 
 | |
|         char* final_msg = NULL;
 | |
|         if (!is_enc)
 | |
|         {
 | |
|             final_msg = recv_string;
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             size_t gcrypt_max_len = B64_DECODE_LEN(strlen(recv_string));
 | |
|             char* gcrypt_buf = dawn_malloc(gcrypt_max_len);
 | |
|             if (!gcrypt_buf) {
 | |
|                 dawnlog_error("Received network error: not enough memory\n");
 | |
|                 return 0;
 | |
|             }
 | |
| 
 | |
|             size_t gcrypt_len = b64_decode(recv_string, gcrypt_buf, gcrypt_max_len);
 | |
|             final_msg = gcrypt_decrypt_msg(gcrypt_buf, gcrypt_len);
 | |
| 
 | |
|             dawn_free(gcrypt_buf);
 | |
|             gcrypt_buf = NULL;
 | |
| 
 | |
|             if (!final_msg) {
 | |
|                 dawnlog_error("Received network error: not enough memory\n");
 | |
|                 return 0;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         dawnlog_debug("Received network message: %s\n", final_msg);
 | |
|         handle_network_msg(final_msg);
 | |
| 
 | |
|         if (is_enc)
 | |
|         {
 | |
|             dawn_free(final_msg);
 | |
|             final_msg = NULL;
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| void* receive_msg(void* args) {
 | |
|     return receive_msg_inner(args, false);
 | |
| }
 | |
| 
 | |
| void *receive_msg_enc(void *args) {
 | |
|     return receive_msg_inner(args, true);
 | |
| }
 | |
| 
 | |
| int send_string(char *msg, bool is_enc) {
 | |
|     pthread_mutex_lock(&send_mutex);
 | |
| 
 | |
|     char* final_msg = NULL;
 | |
|     size_t msglen = 0;
 | |
| 
 | |
|     if (!is_enc)
 | |
|     {
 | |
|         // Include NUL terminator in message
 | |
|         final_msg = msg;
 | |
|         msglen = strlen(msg) + 1;
 | |
| 
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         int gcrypt_len = 0;
 | |
|         // Include NUL terminator in encrypted message
 | |
|         char* gcrypt_buf = gcrypt_encrypt_msg(msg, strlen(msg) + 1, &gcrypt_len);
 | |
|         if (!gcrypt_buf) {
 | |
|             dawnlog_error("sendto() error: not enough memory\n");
 | |
|             pthread_mutex_unlock(&send_mutex);
 | |
|             exit(EXIT_FAILURE);
 | |
|         }
 | |
| 
 | |
|         size_t b64_max_len = B64_ENCODE_LEN(gcrypt_len);
 | |
|         char* final_msg = dawn_malloc(b64_max_len);
 | |
|         if (!final_msg) {
 | |
|             dawnlog_error("sendto() error: not enough memory\n");
 | |
|             dawn_free(gcrypt_buf);
 | |
|             gcrypt_buf = NULL;
 | |
|             pthread_mutex_unlock(&send_mutex);
 | |
|             exit(EXIT_FAILURE);
 | |
|         }
 | |
| 
 | |
|         // very important to use actual length of string because of '\0' in encrypted msg
 | |
|         msglen = b64_encode(gcrypt_buf, gcrypt_len, final_msg, b64_max_len);
 | |
| 
 | |
|         dawn_free(gcrypt_buf);
 | |
|         gcrypt_buf = NULL;
 | |
|     }
 | |
| 
 | |
|     if (sendto(sock,
 | |
|         final_msg,
 | |
|         msglen,
 | |
|         0,
 | |
|         (struct sockaddr*)&addr,
 | |
|         sizeof(addr)) < 0) {
 | |
|         dawnlog_perror("sendto()");
 | |
| 
 | |
|         // Tidy up probbaly unnecessary if we're exiting, but...
 | |
|         if (is_enc)
 | |
|             dawn_free(final_msg);
 | |
|         pthread_mutex_unlock(&send_mutex);
 | |
| 
 | |
|         exit(EXIT_FAILURE);
 | |
|     }
 | |
| 
 | |
|     if (is_enc)
 | |
|     {
 | |
|         dawn_free(final_msg);
 | |
|         final_msg = NULL;
 | |
|     }
 | |
| 
 | |
|     pthread_mutex_unlock(&send_mutex);
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| void close_socket() {
 | |
|     if (multicast_socket) {
 | |
|         remove_multicast_socket(sock);
 | |
|     }
 | |
|     close(sock);
 | |
| }
 |