Re: [PATCH BlueZ] mesh: Offload loopback packets to l_idle_onshot()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Applied
On Thu, 2020-01-16 at 23:16 -0800, Brian Gix wrote:
> Any packet that may be handled internally by the daemon must be sent in
> it's own idle_oneshot context, to prevent multiple nodes from handling
> and responding in the same context, eventually corrupting memory.
> 
> This addresses the following crash:
> Program terminated with signal SIGSEGV, Segmentation fault.
>  0  tcache_get (tc_idx=0) at malloc.c:2951
>      2951   tcache->entries[tc_idx] = e->next;
> (gdb) bt
>  0  tcache_get (tc_idx=0) at malloc.c:2951
>  1  __GI___libc_malloc (bytes=bytes@entry=16) at malloc.c:3058
>  2  0x0000564cff9bc1de in l_malloc (size=size@entry=16) at ell/util.c:62
>  3  0x0000564cff9bd46b in l_queue_push_tail (queue=0x564d000c9710, data=data@entry=0x564d000d0d60) at
> ell/queue.c:136
>  4  0x0000564cff9beabd in idle_add (callback=callback@entry=0x564cff9be4e0 <oneshot_callback>, 
> user_data=user_data@entry=0x564d000d4700,
>     flags=flags@entry=268435456, destroy=destroy@entry=0x564cff9be4c0 <idle_destroy>) at ell/main.c:292
>  5  0x0000564cff9be5f7 in l_idle_oneshot (callback=callback@entry=0x564cff998bc0 <tx_worker>, 
> user_data=user_data@entry=0x564d000d83f0,
>     destroy=destroy@entry=0x0) at ell/idle.c:144
>  6  0x0000564cff998326 in send_tx (io=<optimized out>, info=0x7ffd035503f4, data=<optimized out>,
> len=<optimized out>)
>     at mesh/mesh-io-generic.c:637
>  7  0x0000564cff99675a in send_network_beacon (key=0x564d000cfee0) at mesh/net-keys.c:355
>  8  snb_timeout (timeout=0x564d000dd730, user_data=0x564d000cfee0) at mesh/net-keys.c:364
>  9  0x0000564cff9bdca2 in timeout_callback (fd=<optimized out>, events=<optimized out>,
> user_data=0x564d000dd730) at ell/timeout.c:81
>  10 timeout_callback (fd=<optimized out>, events=<optimized out>, user_data=0x564d000dd730) at
> ell/timeout.c:70
>  11 0x0000564cff9bedcd in l_main_iterate (timeout=<optimized out>) at ell/main.c:473
>  12 0x0000564cff9bee7c in l_main_run () at ell/main.c:520
>  13 l_main_run () at ell/main.c:502
>  14 0x0000564cff9bf08c in l_main_run_with_signal (callback=<optimized out>, user_data=0x0) at ell/main.c:642
>  15 0x0000564cff994b64 in main (argc=<optimized out>, argv=0x7ffd03550668) at mesh/main.c:268
> ---
>  mesh/net.c | 50 +++++++++++++++++++++++++++++++++++++-------------
>  1 file changed, 37 insertions(+), 13 deletions(-)
> 
> diff --git a/mesh/net.c b/mesh/net.c
> index 35388beec..219217793 100644
> --- a/mesh/net.c
> +++ b/mesh/net.c
> @@ -241,6 +241,12 @@ struct net_queue_data {
>  	bool seen;
>  };
>  
> +struct oneshot_tx {
> +	struct mesh_net *net;
> +	uint8_t size;
> +	uint8_t packet[30];
> +};
> +
>  struct net_beacon_data {
>  	uint32_t key_id;
>  	uint32_t ivi;
> @@ -2247,24 +2253,35 @@ static void send_relay_pkt(struct mesh_net *net, uint8_t *data, uint8_t size)
>  	mesh_io_send(io, &info, packet, size + 1);
>  }
>  
> -static void send_msg_pkt(struct mesh_net *net, uint8_t *packet, uint8_t size)
> +static bool simple_match(const void *a, const void *b)
>  {
> -	struct mesh_io *io = net->io;
> +	return a == b;
> +}
> +
> +static void send_msg_pkt_oneshot(void *user_data)
> +{
> +	struct oneshot_tx *tx = user_data;
> +	struct mesh_net *net;
>  	struct mesh_io_send_info info;
>  	struct net_queue_data net_data = {
>  		.info = NULL,
> -		.data = packet + 1,
> -		.len = size - 1,
> +		.data = tx->packet + 1,
> +		.len = tx->size - 1,
>  		.relay_advice = RELAY_NONE,
>  	};
>  
>  	/* Send to local nodes first */
>  	l_queue_foreach(nets, net_rx, &net_data);
>  
> -	if (net_data.relay_advice == RELAY_DISALLOWED)
> +	/* Make sure specific network still valid */
> +	net = l_queue_find(nets, simple_match, tx->net);
> +
> +	if (!net || net_data.relay_advice == RELAY_DISALLOWED) {
> +		l_free(tx);
>  		return;
> +	}
>  
> -	packet[0] = MESH_AD_TYPE_NETWORK;
> +	tx->packet[0] = MESH_AD_TYPE_NETWORK;
>  	info.type = MESH_IO_TIMING_TYPE_GENERAL;
>  	info.u.gen.interval = net->tx_interval;
>  	info.u.gen.cnt = net->tx_cnt;
> @@ -2272,7 +2289,19 @@ static void send_msg_pkt(struct mesh_net *net, uint8_t *packet, uint8_t size)
>  	/* No extra randomization when sending regular mesh messages */
>  	info.u.gen.max_delay = DEFAULT_MIN_DELAY;
>  
> -	mesh_io_send(io, &info, packet, size);
> +	mesh_io_send(net->io, &info, tx->packet, tx->size);
> +	l_free(tx);
> +}
> +
> +static void send_msg_pkt(struct mesh_net *net, uint8_t *packet, uint8_t size)
> +{
> +	struct oneshot_tx *tx = l_new(struct oneshot_tx, 1);
> +
> +	tx->net = net;
> +	tx->size = size;
> +	memcpy(tx->packet, packet, size);
> +
> +	l_idle_oneshot(send_msg_pkt_oneshot, tx, NULL);
>  }
>  
>  static enum _relay_advice packet_received(void *user_data,
> @@ -2847,11 +2876,6 @@ bool mesh_net_set_key(struct mesh_net *net, uint16_t idx, const uint8_t *key,
>  	return true;
>  }
>  
> -static bool is_this_net(const void *a, const void *b)
> -{
> -	return a == b;
> -}
> -
>  bool mesh_net_attach(struct mesh_net *net, struct mesh_io *io)
>  {
>  	bool first;
> @@ -2874,7 +2898,7 @@ bool mesh_net_attach(struct mesh_net *net, struct mesh_io *io)
>  							net_msg_recv, NULL);
>  	}
>  
> -	if (l_queue_find(nets, is_this_net, net))
> +	if (l_queue_find(nets, simple_match, net))
>  		return false;
>  
>  	l_queue_push_head(nets, net);




[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux