Quellcode durchsuchen

PacketPassFairQueue: enforce MTU limit through error not assertion

ambrop7 vor 14 Jahren
Ursprung
Commit
3de3e985ef

+ 7 - 4
client/DataProto.c

@@ -243,7 +243,10 @@ int DataProtoSink_Init (DataProtoSink *o, BReactor *reactor, PacketPassInterface
     PacketPassInactivityMonitor_Force(&o->monitor);
     
     // init queue
-    PacketPassFairQueue_Init(&o->queue, PacketPassInactivityMonitor_GetInput(&o->monitor), BReactor_PendingGroup(o->reactor), 1, 1);
+    if (!PacketPassFairQueue_Init(&o->queue, PacketPassInactivityMonitor_GetInput(&o->monitor), BReactor_PendingGroup(o->reactor), 1, 1)) {
+        BLog(BLOG_ERROR, "PacketPassFairQueue_Init failed");
+        goto fail1;
+    }
     
     // init keepalive queue flow
     PacketPassFairQueueFlow_Init(&o->ka_qflow, &o->queue);
@@ -257,7 +260,7 @@ int DataProtoSink_Init (DataProtoSink *o, BReactor *reactor, PacketPassInterface
     // init keepalive buffer
     if (!SinglePacketBuffer_Init(&o->ka_buffer, PacketRecvBlocker_GetOutput(&o->ka_blocker), PacketPassFairQueueFlow_GetInput(&o->ka_qflow), BReactor_PendingGroup(o->reactor))) {
         BLog(BLOG_ERROR, "SinglePacketBuffer_Init failed");
-        goto fail1;
+        goto fail2;
     }
     
     // init receive timer
@@ -275,14 +278,14 @@ int DataProtoSink_Init (DataProtoSink *o, BReactor *reactor, PacketPassInterface
     
     DebugCounter_Init(&o->d_ctr);
     DebugObject_Init(&o->d_obj);
-    
     return 1;
     
-fail1:
+fail2:
     PacketRecvBlocker_Free(&o->ka_blocker);
     DataProtoKeepaliveSource_Free(&o->ka_source);
     PacketPassFairQueueFlow_Free(&o->ka_qflow);
     PacketPassFairQueue_Free(&o->queue);
+fail1:
     PacketPassInactivityMonitor_Free(&o->monitor);
     PacketPassNotifier_Free(&o->notifier);
     return 0;

+ 5 - 1
client/client.c

@@ -2726,7 +2726,11 @@ void server_handler_ready (void *user, peerid_t param_my_id, uint32_t ext_ip)
     DPReceiveDevice_SetPeerID(&device_output_dprd, my_id);
     
     // init server queue
-    PacketPassFairQueue_Init(&server_queue, ServerConnection_GetSendInterface(&server), BReactor_PendingGroup(&ss), 0, 1);
+    if (!PacketPassFairQueue_Init(&server_queue, ServerConnection_GetSendInterface(&server), BReactor_PendingGroup(&ss), 0, 1)) {
+        BLog(BLOG_ERROR, "PacketPassFairQueue_Init failed");
+        terminate();
+        return;
+    }
     
     // set server ready
     server_ready = 1;

+ 4 - 1
examples/fairqueue_test.c

@@ -114,7 +114,10 @@ int main ()
     TimerPacketSink_Init(&sink, &reactor, 500, OUTPUT_INTERVAL);
     
     // initialize queue
-    PacketPassFairQueue_Init(&fq, TimerPacketSink_GetInput(&sink), BReactor_PendingGroup(&reactor), 1, 1);
+    if (!PacketPassFairQueue_Init(&fq, TimerPacketSink_GetInput(&sink), BReactor_PendingGroup(&reactor), 1, 1)) {
+        DEBUG("PacketPassFairQueue_Init failed");
+        return 1;
+    }
     
     // initialize inputs
     for (int i = 0; i < NUM_INPUTS; i++) {

+ 4 - 1
examples/fairqueue_test2.c

@@ -53,7 +53,10 @@ int main ()
     
     // initialize queue
     PacketPassFairQueue fq;
-    PacketPassFairQueue_Init(&fq, RandomPacketSink_GetInput(&sink), BReactor_PendingGroup(&reactor), 0, 1);
+    if (!PacketPassFairQueue_Init(&fq, RandomPacketSink_GetInput(&sink), BReactor_PendingGroup(&reactor), 0, 1)) {
+        DEBUG("PacketPassFairQueue_Init failed");
+        return 1;
+    }
     
     // initialize source 1
     PacketPassFairQueueFlow flow1;

+ 13 - 3
flow/PacketPassFairQueue.c

@@ -210,11 +210,9 @@ static void output_handler_done (PacketPassFairQueue *m)
     }
 }
 
-void PacketPassFairQueue_Init (PacketPassFairQueue *m, PacketPassInterface *output, BPendingGroup *pg, int use_cancel, int packet_weight)
+int PacketPassFairQueue_Init (PacketPassFairQueue *m, PacketPassInterface *output, BPendingGroup *pg, int use_cancel, int packet_weight)
 {
-    ASSERT(PacketPassInterface_GetMTU(output) <= FAIRQUEUE_MAX_TIME)
     ASSERT(packet_weight > 0)
-    ASSERT(packet_weight <= FAIRQUEUE_MAX_TIME - PacketPassInterface_GetMTU(output))
     ASSERT(use_cancel == 0 || use_cancel == 1)
     ASSERT(!use_cancel || PacketPassInterface_HasCancel(output))
     
@@ -224,6 +222,14 @@ void PacketPassFairQueue_Init (PacketPassFairQueue *m, PacketPassInterface *outp
     m->use_cancel = use_cancel;
     m->packet_weight = packet_weight;
     
+    // make sure that (output MTU + packet_weight <= FAIRQUEUE_MAX_TIME)
+    if (!(
+        (PacketPassInterface_GetMTU(output) <= FAIRQUEUE_MAX_TIME) &&
+        (packet_weight <= FAIRQUEUE_MAX_TIME - PacketPassInterface_GetMTU(output))
+    )) {
+        goto fail0;
+    }
+    
     // init output
     PacketPassInterface_Sender_Init(m->output, (PacketPassInterface_handler_done)output_handler_done, m);
     
@@ -247,6 +253,10 @@ void PacketPassFairQueue_Init (PacketPassFairQueue *m, PacketPassInterface *outp
     
     DebugObject_Init(&m->d_obj);
     DebugCounter_Init(&m->d_ctr);
+    return 1;
+    
+fail0:
+    return 0;
 }
 
 void PacketPassFairQueue_Free (PacketPassFairQueue *m)

+ 3 - 2
flow/PacketPassFairQueue.h

@@ -29,6 +29,7 @@
 
 #include <stdint.h>
 
+#include <misc/debug.h>
 #include <misc/debugcounter.h>
 #include <structure/BHeap.h>
 #include <structure/LinkedList2.h>
@@ -80,7 +81,6 @@ typedef struct PacketPassFairQueueFlow_s {
 
 /**
  * Initializes the queue.
- * (output MTU + packet_weight <= FAIRQUEUE_MAX_TIME) must hold.
  *
  * @param m the object
  * @param output output interface
@@ -89,8 +89,9 @@ typedef struct PacketPassFairQueueFlow_s {
  *                   If 1, output must support cancel functionality.
  * @param packet_weight additional weight a packet bears. Must be >0, to keep
  *                      the queue fair for zero size packets.
+ * @return 1 on success, 0 on failure (because output MTU is too large)
  */
-void PacketPassFairQueue_Init (PacketPassFairQueue *m, PacketPassInterface *output, BPendingGroup *pg, int use_cancel, int packet_weight);
+int PacketPassFairQueue_Init (PacketPassFairQueue *m, PacketPassInterface *output, BPendingGroup *pg, int use_cancel, int packet_weight) WARN_UNUSED;
 
 /**
  * Frees the queue.

+ 7 - 1
server/server.c

@@ -1020,13 +1020,19 @@ int client_init_io (struct client_data *client)
     PacketPassPriorityQueueFlow_Init(&client->output_peers_qflow, &client->output_priorityqueue, 0);
     
     // init fair queue (for different peers)
-    PacketPassFairQueue_Init(&client->output_peers_fairqueue, PacketPassPriorityQueueFlow_GetInput(&client->output_peers_qflow), BReactor_PendingGroup(&ss), 0, 1);
+    if (!PacketPassFairQueue_Init(&client->output_peers_fairqueue, PacketPassPriorityQueueFlow_GetInput(&client->output_peers_qflow), BReactor_PendingGroup(&ss), 0, 1)) {
+        client_log(client, BLOG_ERROR, "PacketPassFairQueue_Init failed");
+        goto fail3;
+    }
     
     // init list of flows
     LinkedList2_Init(&client->output_peers_flows);
     
     return 1;
     
+fail3:
+    PacketPassPriorityQueueFlow_Free(&client->output_peers_qflow);
+    PacketProtoFlow_Free(&client->output_control_oflow);
 fail2:
     PacketPassPriorityQueueFlow_Free(&client->output_control_qflow);
     // free output common

+ 12 - 5
tun2socks/SocksUdpGwClient.c

@@ -152,8 +152,8 @@ static void udpgw_handler_received (SocksUdpGwClient *o, BAddr local_addr, BAddr
     return;
 }
 
-void SocksUdpGwClient_Init (SocksUdpGwClient *o, int udp_mtu, int max_connections, int send_buffer_size, btime_t keepalive_time, BAddr socks_server_addr, BAddr remote_udpgw_addr, btime_t reconnect_time, BReactor *reactor, void *user,
-                            SocksUdpGwClient_handler_received handler_received)
+int SocksUdpGwClient_Init (SocksUdpGwClient *o, int udp_mtu, int max_connections, int send_buffer_size, btime_t keepalive_time, BAddr socks_server_addr, BAddr remote_udpgw_addr, btime_t reconnect_time, BReactor *reactor, void *user,
+                           SocksUdpGwClient_handler_received handler_received)
 {
     ASSERT(udp_mtu >= 0)
     ASSERT(udpgw_compute_mtu(udp_mtu) >= 0)
@@ -172,9 +172,12 @@ void SocksUdpGwClient_Init (SocksUdpGwClient *o, int udp_mtu, int max_connection
     o->handler_received = handler_received;
     
     // init udpgw client
-    UdpGwClient_Init(&o->udpgw_client, udp_mtu, max_connections, send_buffer_size, keepalive_time, o->reactor, o,
-                     (UdpGwClient_handler_servererror)udpgw_handler_servererror,
-                     (UdpGwClient_handler_received)udpgw_handler_received);
+    if (!UdpGwClient_Init(&o->udpgw_client, udp_mtu, max_connections, send_buffer_size, keepalive_time, o->reactor, o,
+                          (UdpGwClient_handler_servererror)udpgw_handler_servererror,
+                          (UdpGwClient_handler_received)udpgw_handler_received
+    )) {
+        goto fail0;
+    }
     
     // init reconnect timer
     BTimer_Init(&o->reconnect_timer, reconnect_time, (BTimer_handler)reconnect_timer_handler, o);
@@ -186,6 +189,10 @@ void SocksUdpGwClient_Init (SocksUdpGwClient *o, int udp_mtu, int max_connection
     try_connect(o);
     
     DebugObject_Init(&o->d_obj);
+    return 1;
+    
+fail0:
+    return 0;
 }
 
 void SocksUdpGwClient_Free (SocksUdpGwClient *o)

+ 3 - 2
tun2socks/SocksUdpGwClient.h

@@ -23,6 +23,7 @@
 #ifndef BADVPN_TUN2SOCKS_SOCKSUDPGWCLIENT_H
 #define BADVPN_TUN2SOCKS_SOCKSUDPGWCLIENT_H
 
+#include <misc/debug.h>
 #include <base/DebugObject.h>
 #include <system/BReactor.h>
 #include <udpgw_client/UdpGwClient.h>
@@ -45,8 +46,8 @@ typedef struct {
     DebugObject d_obj;
 } SocksUdpGwClient;
 
-void SocksUdpGwClient_Init (SocksUdpGwClient *o, int udp_mtu, int max_connections, int send_buffer_size, btime_t keepalive_time, BAddr socks_server_addr, BAddr remote_udpgw_addr, btime_t reconnect_time, BReactor *reactor, void *user,
-                            SocksUdpGwClient_handler_received handler_received);
+int SocksUdpGwClient_Init (SocksUdpGwClient *o, int udp_mtu, int max_connections, int send_buffer_size, btime_t keepalive_time, BAddr socks_server_addr, BAddr remote_udpgw_addr, btime_t reconnect_time, BReactor *reactor, void *user,
+                           SocksUdpGwClient_handler_received handler_received) WARN_UNUSED;
 void SocksUdpGwClient_Free (SocksUdpGwClient *o);
 void SocksUdpGwClient_SubmitPacket (SocksUdpGwClient *o, BAddr local_addr, BAddr remote_addr, const uint8_t *data, int data_len);
 

+ 6 - 2
tun2socks/tun2socks.c

@@ -312,8 +312,12 @@ int main (int argc, char **argv)
         }
         
         // init udpgw client
-        SocksUdpGwClient_Init(&udpgw_client, udp_mtu, DEFAULT_UDPGW_MAX_CONNECTIONS, options.udpgw_connection_buffer_size, UDPGW_KEEPALIVE_TIME,
-                              socks_server_addr, udpgw_remote_server_addr, UDPGW_RECONNECT_TIME, &ss, NULL, udpgw_client_handler_received);
+        if (!SocksUdpGwClient_Init(&udpgw_client, udp_mtu, DEFAULT_UDPGW_MAX_CONNECTIONS, options.udpgw_connection_buffer_size, UDPGW_KEEPALIVE_TIME,
+                                   socks_server_addr, udpgw_remote_server_addr, UDPGW_RECONNECT_TIME, &ss, NULL, udpgw_client_handler_received
+        )) {
+            BLog(BLOG_ERROR, "SocksUdpGwClient_Init failed");
+            goto fail4a;
+        }
     }
     
     // init lwip init job

+ 7 - 1
udpgw/udpgw.c

@@ -572,7 +572,10 @@ void listener_handler (BListener *listener)
     PacketStreamSender_Init(&client->send_sender, BConnection_SendAsync_GetIf(&client->con), pp_mtu, BReactor_PendingGroup(&ss));
     
     // init send queue
-    PacketPassFairQueue_Init(&client->send_queue, PacketStreamSender_GetInput(&client->send_sender), BReactor_PendingGroup(&ss), 0, 1);
+    if (!PacketPassFairQueue_Init(&client->send_queue, PacketStreamSender_GetInput(&client->send_sender), BReactor_PendingGroup(&ss), 0, 1)) {
+        BLog(BLOG_ERROR, "PacketPassFairQueue_Init failed");
+        goto fail3;
+    }
     
     // init connections tree
     BAVL_Init(&client->connections_tree, OFFSET_DIFF(struct connection, conid, connections_tree_node), (BAVL_comparator)uint16_comparator, NULL);
@@ -594,6 +597,9 @@ void listener_handler (BListener *listener)
     
     return;
     
+fail3:
+    PacketStreamSender_Free(&client->send_sender);
+    PacketProtoDecoder_Free(&client->recv_decoder);
 fail2:
     PacketPassInterface_Free(&client->recv_if);
     BReactor_RemoveTimer(&ss, &client->disconnect_timer);

+ 12 - 4
udpgw_client/UdpGwClient.c

@@ -373,9 +373,9 @@ static struct UdpGwClient_connection * reuse_connection (UdpGwClient *o, struct
     return con;
 }
 
-void UdpGwClient_Init (UdpGwClient *o, int udp_mtu, int max_connections, int send_buffer_size, btime_t keepalive_time, BReactor *reactor, void *user,
-                       UdpGwClient_handler_servererror handler_servererror,
-                       UdpGwClient_handler_received handler_received)
+int UdpGwClient_Init (UdpGwClient *o, int udp_mtu, int max_connections, int send_buffer_size, btime_t keepalive_time, BReactor *reactor, void *user,
+                      UdpGwClient_handler_servererror handler_servererror,
+                      UdpGwClient_handler_received handler_received)
 {
     ASSERT(udp_mtu >= 0)
     ASSERT(udpgw_compute_mtu(udp_mtu) >= 0)
@@ -424,7 +424,9 @@ void UdpGwClient_Init (UdpGwClient *o, int udp_mtu, int max_connections, int sen
     PacketPassInactivityMonitor_Init(&o->send_monitor, PacketPassConnector_GetInput(&o->send_connector), o->reactor, o->keepalive_time, (PacketPassInactivityMonitor_handler)send_monitor_handler, o);
     
     // init send queue
-    PacketPassFairQueue_Init(&o->send_queue, PacketPassInactivityMonitor_GetInput(&o->send_monitor), BReactor_PendingGroup(o->reactor), 0, 1);
+    if (!PacketPassFairQueue_Init(&o->send_queue, PacketPassInactivityMonitor_GetInput(&o->send_monitor), BReactor_PendingGroup(o->reactor), 0, 1)) {
+        goto fail0;
+    }
     
     // construct keepalive packet
     o->keepalive_packet.pp.len = sizeof(o->keepalive_packet.udpgw);
@@ -445,6 +447,12 @@ void UdpGwClient_Init (UdpGwClient *o, int udp_mtu, int max_connections, int sen
     o->have_server = 0;
     
     DebugObject_Init(&o->d_obj);
+    return 1;
+    
+fail0:
+    PacketPassInactivityMonitor_Free(&o->send_monitor);
+    PacketPassConnector_Free(&o->send_connector);
+    return 0;
 }
 
 void UdpGwClient_Free (UdpGwClient *o)

+ 3 - 3
udpgw_client/UdpGwClient.h

@@ -95,9 +95,9 @@ struct UdpGwClient_connection {
     LinkedList1Node connections_list_node;
 };
 
-void UdpGwClient_Init (UdpGwClient *o, int udp_mtu, int max_connections, int send_buffer_size, btime_t keepalive_time, BReactor *reactor, void *user,
-                       UdpGwClient_handler_servererror handler_servererror,
-                       UdpGwClient_handler_received handler_received);
+int UdpGwClient_Init (UdpGwClient *o, int udp_mtu, int max_connections, int send_buffer_size, btime_t keepalive_time, BReactor *reactor, void *user,
+                      UdpGwClient_handler_servererror handler_servererror,
+                      UdpGwClient_handler_received handler_received) WARN_UNUSED;
 void UdpGwClient_Free (UdpGwClient *o);
 void UdpGwClient_SubmitPacket (UdpGwClient *o, BAddr local_addr, BAddr remote_addr, const uint8_t *data, int data_len);
 int UdpGwClient_ConnectServer (UdpGwClient *o, StreamPassInterface *send_if, StreamRecvInterface *recv_if) WARN_UNUSED;