Переглянути джерело

minor changes, move OTP warning to SPProtoEncoder

ambrop7 15 роки тому
батько
коміт
d1ab2294b8
6 змінених файлів з 116 додано та 126 видалено
  1. 46 73
      client/DatagramPeerIO.c
  2. 17 22
      client/DatagramPeerIO.h
  3. 2 6
      client/client.c
  4. 31 11
      flow/SPProtoEncoder.c
  5. 18 13
      flow/SPProtoEncoder.h
  6. 2 1
      protocol/fragmentproto.h

+ 46 - 73
client/DatagramPeerIO.c

@@ -36,7 +36,7 @@
 #define DATAGRAMPEERIO_COMPONENT_SINK 1
 #define DATAGRAMPEERIO_COMPONENT_SINK 1
 #define DATAGRAMPEERIO_COMPONENT_SOURCE 2
 #define DATAGRAMPEERIO_COMPONENT_SOURCE 2
 
 
-static int init_persistent_io (DatagramPeerIO *o, btime_t latency, int num_frames, PacketPassInterface *recv_userif);
+static int init_persistent_io (DatagramPeerIO *o, btime_t latency, int num_frames, PacketPassInterface *recv_userif, int otp_warning_count, DatagramPeerIO_handler_otp_warning handler_otp_warning, void *user);
 static void free_persistent_io (DatagramPeerIO *o);
 static void free_persistent_io (DatagramPeerIO *o);
 static void init_sending (DatagramPeerIO *o, BAddr addr, BIPAddr local_addr);
 static void init_sending (DatagramPeerIO *o, BAddr addr, BIPAddr local_addr);
 static void free_sending (DatagramPeerIO *o);
 static void free_sending (DatagramPeerIO *o);
@@ -45,9 +45,8 @@ static void free_receiving (DatagramPeerIO *o);
 static void error_handler (DatagramPeerIO *o, int component, const void *data);
 static void error_handler (DatagramPeerIO *o, int component, const void *data);
 static void reset_mode (DatagramPeerIO *o);
 static void reset_mode (DatagramPeerIO *o);
 static void recv_decoder_notifier_handler (DatagramPeerIO *o, uint8_t *data, int data_len);
 static void recv_decoder_notifier_handler (DatagramPeerIO *o, uint8_t *data, int data_len);
-static void send_encoder_notifier_handler (DatagramPeerIO *o, uint8_t *data, int data_len);
 
 
-int init_persistent_io (DatagramPeerIO *o, btime_t latency, int num_frames, PacketPassInterface *recv_userif)
+int init_persistent_io (DatagramPeerIO *o, btime_t latency, int num_frames, PacketPassInterface *recv_userif, int otp_warning_count, DatagramPeerIO_handler_otp_warning handler_otp_warning, void *user)
 {
 {
     // init error domain
     // init error domain
     FlowErrorDomain_Init(&o->domain, (FlowErrorDomain_handler)error_handler, o);
     FlowErrorDomain_Init(&o->domain, (FlowErrorDomain_handler)error_handler, o);
@@ -84,22 +83,16 @@ int init_persistent_io (DatagramPeerIO *o, btime_t latency, int num_frames, Pack
     FragmentProtoDisassembler_Init(&o->send_disassembler, o->reactor, o->payload_mtu, o->spproto_payload_mtu, -1, latency);
     FragmentProtoDisassembler_Init(&o->send_disassembler, o->reactor, o->payload_mtu, o->spproto_payload_mtu, -1, latency);
     
     
     // init encoder
     // init encoder
-    if (!SPProtoEncoder_Init(&o->send_encoder, FragmentProtoDisassembler_GetOutput(&o->send_disassembler), o->sp_params, BReactor_PendingGroup(o->reactor))) {
+    if (!SPProtoEncoder_Init(&o->send_encoder, FragmentProtoDisassembler_GetOutput(&o->send_disassembler), o->sp_params, otp_warning_count, handler_otp_warning, user, BReactor_PendingGroup(o->reactor))) {
         BLog(BLOG_ERROR, "SPProtoEncoder_Init failed");
         BLog(BLOG_ERROR, "SPProtoEncoder_Init failed");
         goto fail3;
         goto fail3;
     }
     }
     
     
-    // init notifier
-    PacketRecvNotifier_Init(&o->send_notifier, SPProtoEncoder_GetOutput(&o->send_encoder), BReactor_PendingGroup(o->reactor));
-    if (SPPROTO_HAVE_OTP(o->sp_params)) {
-        PacketRecvNotifier_SetHandler(&o->send_notifier, (PacketRecvNotifier_handler_notify)send_encoder_notifier_handler, o);
-    }
-    
     // init connector
     // init connector
     PacketPassConnector_Init(&o->send_connector, o->effective_socket_mtu, BReactor_PendingGroup(o->reactor));
     PacketPassConnector_Init(&o->send_connector, o->effective_socket_mtu, BReactor_PendingGroup(o->reactor));
     
     
     // init buffer
     // init buffer
-    if (!SinglePacketBuffer_Init(&o->send_buffer, PacketRecvNotifier_GetOutput(&o->send_notifier), PacketPassConnector_GetInput(&o->send_connector), BReactor_PendingGroup(o->reactor))) {
+    if (!SinglePacketBuffer_Init(&o->send_buffer, SPProtoEncoder_GetOutput(&o->send_encoder), PacketPassConnector_GetInput(&o->send_connector), BReactor_PendingGroup(o->reactor))) {
         BLog(BLOG_ERROR, "SinglePacketBuffer_Init failed");
         BLog(BLOG_ERROR, "SinglePacketBuffer_Init failed");
         goto fail4;
         goto fail4;
     }
     }
@@ -108,7 +101,6 @@ int init_persistent_io (DatagramPeerIO *o, btime_t latency, int num_frames, Pack
 
 
 fail4:
 fail4:
     PacketPassConnector_Free(&o->send_connector);
     PacketPassConnector_Free(&o->send_connector);
-    PacketRecvNotifier_Free(&o->send_notifier);
     SPProtoEncoder_Free(&o->send_encoder);
     SPProtoEncoder_Free(&o->send_encoder);
 fail3:
 fail3:
     FragmentProtoDisassembler_Free(&o->send_disassembler);
     FragmentProtoDisassembler_Free(&o->send_disassembler);
@@ -128,7 +120,6 @@ void free_persistent_io (DatagramPeerIO *o)
     // free sending base
     // free sending base
     SinglePacketBuffer_Free(&o->send_buffer);
     SinglePacketBuffer_Free(&o->send_buffer);
     PacketPassConnector_Free(&o->send_connector);
     PacketPassConnector_Free(&o->send_connector);
-    PacketRecvNotifier_Free(&o->send_notifier);
     SPProtoEncoder_Free(&o->send_encoder);
     SPProtoEncoder_Free(&o->send_encoder);
     FragmentProtoDisassembler_Free(&o->send_disassembler);
     FragmentProtoDisassembler_Free(&o->send_disassembler);
     
     
@@ -212,36 +203,28 @@ void error_handler (DatagramPeerIO *o, int component, const void *data)
 
 
 void reset_mode (DatagramPeerIO *o)
 void reset_mode (DatagramPeerIO *o)
 {
 {
-    switch (o->mode) {
-        case DATAGRAMPEERIO_MODE_NONE:
-            break;
-        case DATAGRAMPEERIO_MODE_CONNECT:
-            // set default mode
-            o->mode = DATAGRAMPEERIO_MODE_NONE;
-            // free receiving
-            free_receiving(o);
-            // free sending
-            free_sending(o);
-            // free socket
-            BSocket_Free(&o->sock);
-            break;
-        case DATAGRAMPEERIO_MODE_BIND:
-            // set default mode
-            o->mode = DATAGRAMPEERIO_MODE_NONE;
-            // remove recv notifier handler
-            PacketPassNotifier_SetHandler(&o->recv_notifier, NULL, NULL);
-            // free receiving
-            free_receiving(o);
-            // free sending
-            if (o->bind_sending_up) {
-                free_sending(o);
-            }
-            // free socket
-            BSocket_Free(&o->sock);
-            break;
-        default:
-            ASSERT(0);
+    ASSERT(o->mode == DATAGRAMPEERIO_MODE_NONE || o->mode == DATAGRAMPEERIO_MODE_CONNECT || o->mode == DATAGRAMPEERIO_MODE_BIND)
+    
+    if (o->mode == DATAGRAMPEERIO_MODE_NONE) {
+        return;
+    }
+    
+    // free sending
+    if (o->mode == DATAGRAMPEERIO_MODE_CONNECT || o->bind_sending_up) {
+        free_sending(o);
     }
     }
+    
+    // remove recv notifier handler
+    PacketPassNotifier_SetHandler(&o->recv_notifier, NULL, NULL);
+    
+    // free receiving
+    free_receiving(o);
+    
+    // free socket
+    BSocket_Free(&o->sock);
+    
+    // set mode
+    o->mode = DATAGRAMPEERIO_MODE_NONE;
 }
 }
 
 
 void recv_decoder_notifier_handler (DatagramPeerIO *o, uint8_t *data, int data_len)
 void recv_decoder_notifier_handler (DatagramPeerIO *o, uint8_t *data, int data_len)
@@ -266,24 +249,30 @@ void recv_decoder_notifier_handler (DatagramPeerIO *o, uint8_t *data, int data_l
     }
     }
 }
 }
 
 
-void send_encoder_notifier_handler (DatagramPeerIO *o, uint8_t *data, int data_len)
-{
-    ASSERT(SPPROTO_HAVE_OTP(o->sp_params))
-    DebugObject_Access(&o->d_obj);
-    
-    if (o->handler_otp_warning && SPProtoEncoder_GetOTPPosition(&o->send_encoder) == o->handler_otp_warning_num_used) { 
-        o->handler_otp_warning(o->handler_otp_warning_user);
-        return;
-    }
-}
-
-int DatagramPeerIO_Init (DatagramPeerIO *o, BReactor *reactor, int payload_mtu, int socket_mtu, struct spproto_security_params sp_params, btime_t latency, int num_frames, PacketPassInterface *recv_userif)
+int DatagramPeerIO_Init (
+    DatagramPeerIO *o,
+    BReactor *reactor,
+    int payload_mtu,
+    int socket_mtu,
+    struct spproto_security_params sp_params,
+    btime_t latency,
+    int num_frames,
+    PacketPassInterface *recv_userif,
+    int otp_warning_count,
+    DatagramPeerIO_handler_otp_warning handler_otp_warning,
+    void *user
+)
 {
 {
     ASSERT(payload_mtu >= 0)
     ASSERT(payload_mtu >= 0)
     ASSERT(socket_mtu >= 0)
     ASSERT(socket_mtu >= 0)
     spproto_assert_security_params(sp_params);
     spproto_assert_security_params(sp_params);
     ASSERT(num_frames > 0)
     ASSERT(num_frames > 0)
     ASSERT(PacketPassInterface_GetMTU(recv_userif) >= payload_mtu)
     ASSERT(PacketPassInterface_GetMTU(recv_userif) >= payload_mtu)
+    if (SPPROTO_HAVE_OTP(sp_params)) {
+        ASSERT(otp_warning_count > 0)
+        ASSERT(otp_warning_count <= sp_params.otp_num)
+        ASSERT(handler_otp_warning)
+    }
     
     
     // set parameters
     // set parameters
     o->reactor = reactor;
     o->reactor = reactor;
@@ -308,16 +297,11 @@ int DatagramPeerIO_Init (DatagramPeerIO *o, BReactor *reactor, int payload_mtu,
         goto fail1;
         goto fail1;
     }
     }
     
     
-    // set no OTP warning handler
-    if (SPPROTO_HAVE_OTP(o->sp_params)) {
-        o->handler_otp_warning = NULL;
-    }
-    
     // set mode none
     // set mode none
     o->mode = DATAGRAMPEERIO_MODE_NONE;
     o->mode = DATAGRAMPEERIO_MODE_NONE;
     
     
     // init persistent I/O objects
     // init persistent I/O objects
-    if (!init_persistent_io(o, latency, num_frames, recv_userif)) {
+    if (!init_persistent_io(o, latency, num_frames, recv_userif, otp_warning_count, handler_otp_warning, user)) {
         goto fail1;
         goto fail1;
     }
     }
     
     
@@ -429,7 +413,7 @@ fail1:
 
 
 void DatagramPeerIO_SetEncryptionKey (DatagramPeerIO *o, uint8_t *encryption_key)
 void DatagramPeerIO_SetEncryptionKey (DatagramPeerIO *o, uint8_t *encryption_key)
 {
 {
-    ASSERT(o->sp_params.encryption_mode != SPPROTO_ENCRYPTION_MODE_NONE)
+    ASSERT(SPPROTO_HAVE_ENCRYPTION(o->sp_params))
     DebugObject_Access(&o->d_obj);
     DebugObject_Access(&o->d_obj);
     
     
     // set sending key
     // set sending key
@@ -441,7 +425,7 @@ void DatagramPeerIO_SetEncryptionKey (DatagramPeerIO *o, uint8_t *encryption_key
 
 
 void DatagramPeerIO_RemoveEncryptionKey (DatagramPeerIO *o)
 void DatagramPeerIO_RemoveEncryptionKey (DatagramPeerIO *o)
 {
 {
-    ASSERT(o->sp_params.encryption_mode != SPPROTO_ENCRYPTION_MODE_NONE)
+    ASSERT(SPPROTO_HAVE_ENCRYPTION(o->sp_params))
     DebugObject_Access(&o->d_obj);
     DebugObject_Access(&o->d_obj);
     
     
     // remove sending key
     // remove sending key
@@ -486,14 +470,3 @@ void DatagramPeerIO_RemoveOTPRecvSeeds (DatagramPeerIO *o)
     // remove receiving seeds
     // remove receiving seeds
     SPProtoDecoder_RemoveOTPSeeds(&o->recv_decoder);
     SPProtoDecoder_RemoveOTPSeeds(&o->recv_decoder);
 }
 }
-
-void DatagramPeerIO_SetOTPWarningHandler (DatagramPeerIO *o, DatagramPeerIO_handler_otp_warning handler, void *user, int num_used)
-{
-    ASSERT(SPPROTO_HAVE_OTP(o->sp_params))
-    ASSERT(!handler || num_used > 0)
-    DebugObject_Access(&o->d_obj);
-    
-    o->handler_otp_warning = handler;
-    o->handler_otp_warning_user = user;
-    o->handler_otp_warning_num_used = num_used;
-}

+ 17 - 22
client/DatagramPeerIO.h

@@ -48,7 +48,6 @@
 #include <flow/SPProtoDecoder.h>
 #include <flow/SPProtoDecoder.h>
 #include <flow/FragmentProtoAssembler.h>
 #include <flow/FragmentProtoAssembler.h>
 #include <flow/PacketPassNotifier.h>
 #include <flow/PacketPassNotifier.h>
-#include <flow/PacketRecvNotifier.h>
 
 
 /**
 /**
  * Handler function invoked when the number of used OTPs has reached
  * Handler function invoked when the number of used OTPs has reached
@@ -91,7 +90,6 @@ typedef struct {
     // sending base
     // sending base
     FragmentProtoDisassembler send_disassembler;
     FragmentProtoDisassembler send_disassembler;
     SPProtoEncoder send_encoder;
     SPProtoEncoder send_encoder;
-    PacketRecvNotifier send_notifier;
     SinglePacketBuffer send_buffer;
     SinglePacketBuffer send_buffer;
     PacketPassConnector send_connector;
     PacketPassConnector send_connector;
     
     
@@ -102,11 +100,6 @@ typedef struct {
     PacketPassNotifier recv_notifier;
     PacketPassNotifier recv_notifier;
     FragmentProtoAssembler recv_assembler;
     FragmentProtoAssembler recv_assembler;
     
     
-    // OTP warning handler
-    DatagramPeerIO_handler_otp_warning handler_otp_warning;
-    void *handler_otp_warning_user;
-    int handler_otp_warning_num_used;
-    
     // mode
     // mode
     int mode;
     int mode;
     
     
@@ -138,9 +131,25 @@ typedef struct {
  * @param latency latency parameter to {@link FragmentProtoDisassembler_Init}.
  * @param latency latency parameter to {@link FragmentProtoDisassembler_Init}.
  * @param num_frames num_frames parameter to {@link FragmentProtoAssembler_Init}. Must be >0.
  * @param num_frames num_frames parameter to {@link FragmentProtoAssembler_Init}. Must be >0.
  * @param recv_userif interface to pass received packets to the user. Its MTU must be >=payload_mtu.
  * @param recv_userif interface to pass received packets to the user. Its MTU must be >=payload_mtu.
+ * @param otp_warning_count If using OTPs, after how many encoded packets to call the handler.
+ *                          In this case, must be >0 and <=sp_params.otp_num.
+ * @param handler_otp_warning OTP warning handler
+ * @param user value to pass to handler
  * @return 1 on success, 0 on failure
  * @return 1 on success, 0 on failure
  */
  */
-int DatagramPeerIO_Init (DatagramPeerIO *o, BReactor *reactor, int payload_mtu, int socket_mtu, struct spproto_security_params sp_params, btime_t latency, int num_frames, PacketPassInterface *recv_userif) WARN_UNUSED;
+int DatagramPeerIO_Init (
+    DatagramPeerIO *o,
+    BReactor *reactor,
+    int payload_mtu,
+    int socket_mtu,
+    struct spproto_security_params sp_params,
+    btime_t latency,
+    int num_frames,
+    PacketPassInterface *recv_userif,
+    int otp_warning_count,
+    DatagramPeerIO_handler_otp_warning handler_otp_warning,
+    void *user
+) WARN_UNUSED;
 
 
 /**
 /**
  * Frees the object.
  * Frees the object.
@@ -236,18 +245,4 @@ void DatagramPeerIO_AddOTPRecvSeed (DatagramPeerIO *o, uint16_t seed_id, uint8_t
  */
  */
 void DatagramPeerIO_RemoveOTPRecvSeeds (DatagramPeerIO *o);
 void DatagramPeerIO_RemoveOTPRecvSeeds (DatagramPeerIO *o);
 
 
-/**
- * Sets the OTP warning handler.
- * OTPs must be enabled.
- *
- * @param o the object
- * @param handler handler function. NULL to disable handler.
- * @param user value passed to handler function
- * @param num_used after how many used OTPs to invoke the handler. Must be >0 unless handler is NULL.
- *                 The handler will be invoked when exactly that many OTPs have been used. If the handler
- *                 is configured when the warning level has already been reached, it will not be called
- *                 until a new send seed is set or the handler is reconfigured.
- */
-void DatagramPeerIO_SetOTPWarningHandler (DatagramPeerIO *o, DatagramPeerIO_handler_otp_warning handler, void *user, int num_used);
-
 #endif
 #endif

+ 2 - 6
client/client.c

@@ -1399,17 +1399,13 @@ int peer_init_link (struct peer_data *peer)
         // init DatagramPeerIO
         // init DatagramPeerIO
         if (!DatagramPeerIO_Init(
         if (!DatagramPeerIO_Init(
             &peer->pio.udp.pio, &ss, data_mtu, CLIENT_UDP_MTU, sp_params,
             &peer->pio.udp.pio, &ss, data_mtu, CLIENT_UDP_MTU, sp_params,
-            options.fragmentation_latency, PEER_UDP_ASSEMBLER_NUM_FRAMES, &peer->recv_ppi
+            options.fragmentation_latency, PEER_UDP_ASSEMBLER_NUM_FRAMES, &peer->recv_ppi,
+            options.otp_num_warn, (DatagramPeerIO_handler_otp_warning)peer_udp_pio_handler_seed_warning, peer
         )) {
         )) {
             peer_log(peer, BLOG_ERROR, "DatagramPeerIO_Init failed");
             peer_log(peer, BLOG_ERROR, "DatagramPeerIO_Init failed");
             goto fail1;
             goto fail1;
         }
         }
         
         
-        // init OTP warning handler
-        if (SPPROTO_HAVE_OTP(sp_params)) {
-            DatagramPeerIO_SetOTPWarningHandler(&peer->pio.udp.pio, (DatagramPeerIO_handler_otp_warning)peer_udp_pio_handler_seed_warning, peer, options.otp_num_warn);
-        }
-        
         // init send seed state
         // init send seed state
         if (SPPROTO_HAVE_OTP(sp_params)) {
         if (SPPROTO_HAVE_OTP(sp_params)) {
             peer->pio.udp.sendseed_nextid = 0;
             peer->pio.udp.sendseed_nextid = 0;

+ 31 - 11
flow/SPProtoEncoder.c

@@ -109,6 +109,11 @@ static int encode_packet (SPProtoEncoder *o)
     o->in_len = -1;
     o->in_len = -1;
     o->out_have = 0;
     o->out_have = 0;
     PacketRecvInterface_Done(&o->output, out_len);
     PacketRecvInterface_Done(&o->output, out_len);
+    
+    // schedule OTP warning handler
+    if (SPPROTO_HAVE_OTP(o->sp_params) && OTPGenerator_GetPosition(&o->otpgen) == o->otp_warning_count) {
+        BPending_Set(&o->handler_job);
+    }
 }
 }
 
 
 static void maybe_encode (SPProtoEncoder *o)
 static void maybe_encode (SPProtoEncoder *o)
@@ -152,14 +157,31 @@ static void input_handler_done (SPProtoEncoder *o, int data_len)
     }
     }
 }
 }
 
 
-int SPProtoEncoder_Init (SPProtoEncoder *o, PacketRecvInterface *input, struct spproto_security_params sp_params, BPendingGroup *pg)
+static void handler_job_hander (SPProtoEncoder *o)
+{
+    ASSERT(SPPROTO_HAVE_OTP(o->sp_params))
+    DebugObject_Access(&o->d_obj);
+    
+    o->handler(o->user);
+    return;
+}
+
+int SPProtoEncoder_Init (SPProtoEncoder *o, PacketRecvInterface *input, struct spproto_security_params sp_params, int otp_warning_count, SPProtoEncoder_handler handler, void *user, BPendingGroup *pg)
 {
 {
     spproto_assert_security_params(sp_params);
     spproto_assert_security_params(sp_params);
     ASSERT(spproto_carrier_mtu_for_payload_mtu(sp_params, PacketRecvInterface_GetMTU(input)) >= 0)
     ASSERT(spproto_carrier_mtu_for_payload_mtu(sp_params, PacketRecvInterface_GetMTU(input)) >= 0)
+    if (SPPROTO_HAVE_OTP(sp_params)) {
+        ASSERT(otp_warning_count > 0)
+        ASSERT(otp_warning_count <= sp_params.otp_num)
+        ASSERT(handler)
+    }
     
     
-    // init parameters
-    o->sp_params = sp_params;
+    // init arguments
     o->input = input;
     o->input = input;
+    o->sp_params = sp_params;
+    o->otp_warning_count = otp_warning_count;
+    o->handler = handler;
+    o->user = user;
     
     
     // calculate hash size
     // calculate hash size
     if (SPPROTO_HAVE_HASH(o->sp_params)) {
     if (SPPROTO_HAVE_HASH(o->sp_params)) {
@@ -210,6 +232,9 @@ int SPProtoEncoder_Init (SPProtoEncoder *o, PacketRecvInterface *input, struct s
         }
         }
     }
     }
     
     
+    // init handler job
+    BPending_Init(&o->handler_job, pg, (BPending_handler)handler_job_hander, o);
+    
     DebugObject_Init(&o->d_obj);
     DebugObject_Init(&o->d_obj);
     
     
     return 1;
     return 1;
@@ -227,6 +252,9 @@ void SPProtoEncoder_Free (SPProtoEncoder *o)
 {
 {
     DebugObject_Free(&o->d_obj);
     DebugObject_Free(&o->d_obj);
     
     
+    // free handler job
+    BPending_Free(&o->handler_job);
+    
     // free plaintext buffer
     // free plaintext buffer
     if (SPPROTO_HAVE_ENCRYPTION(o->sp_params)) {
     if (SPPROTO_HAVE_ENCRYPTION(o->sp_params)) {
         free(o->buf);
         free(o->buf);
@@ -310,11 +338,3 @@ void SPProtoEncoder_RemoveOTPSeed (SPProtoEncoder *o)
     // reset OTP generator
     // reset OTP generator
     OTPGenerator_Reset(&o->otpgen);
     OTPGenerator_Reset(&o->otpgen);
 }
 }
-
-int SPProtoEncoder_GetOTPPosition (SPProtoEncoder *o)
-{
-    ASSERT(SPPROTO_HAVE_OTP(o->sp_params))
-    DebugObject_Access(&o->d_obj);
-    
-    return OTPGenerator_GetPosition(&o->otpgen);
-}

+ 18 - 13
flow/SPProtoEncoder.h

@@ -36,6 +36,14 @@
 #include <security/OTPGenerator.h>
 #include <security/OTPGenerator.h>
 #include <flow/PacketRecvInterface.h>
 #include <flow/PacketRecvInterface.h>
 
 
+/**
+ * Event context handler called when the remaining number of
+ * OTPs equals the warning number after having encoded a packet.
+ * 
+ * @param user as in {@link SPProtoEncoder_Init}
+ */
+typedef void (*SPProtoEncoder_handler) (void *user);
+
 /**
 /**
  * Object which encodes packets according to SPProto.
  * Object which encodes packets according to SPProto.
  *
  *
@@ -43,7 +51,11 @@
  * Output is with {@link PacketRecvInterface}.
  * Output is with {@link PacketRecvInterface}.
  */
  */
 typedef struct {
 typedef struct {
+    PacketRecvInterface *input;
     struct spproto_security_params sp_params;
     struct spproto_security_params sp_params;
+    int otp_warning_count;
+    SPProtoEncoder_handler handler;
+    void *user;
     int hash_size;
     int hash_size;
     int enc_block_size;
     int enc_block_size;
     int enc_key_size;
     int enc_key_size;
@@ -51,15 +63,14 @@ typedef struct {
     uint16_t otpgen_seed_id;
     uint16_t otpgen_seed_id;
     int have_encryption_key;
     int have_encryption_key;
     BEncryption encryptor;
     BEncryption encryptor;
-    
     int input_mtu;
     int input_mtu;
     int output_mtu;
     int output_mtu;
-    PacketRecvInterface *input;
     int in_len;
     int in_len;
     PacketRecvInterface output;
     PacketRecvInterface output;
     int out_have;
     int out_have;
     uint8_t *out;
     uint8_t *out;
     uint8_t *buf;
     uint8_t *buf;
+    BPending handler_job;
     DebugObject d_obj;
     DebugObject d_obj;
 } SPProtoEncoder;
 } SPProtoEncoder;
 
 
@@ -71,10 +82,14 @@ typedef struct {
  * @param input input interface. Its MTU must not be too large, i.e. this must hold:
  * @param input input interface. Its MTU must not be too large, i.e. this must hold:
  *              spproto_carrier_mtu_for_payload_mtu(sp_params, input MTU) >= 0
  *              spproto_carrier_mtu_for_payload_mtu(sp_params, input MTU) >= 0
  * @param sp_params SPProto security parameters
  * @param sp_params SPProto security parameters
+ * @param otp_warning_count If using OTPs, after how many encoded packets to call the handler.
+ *                          In this case, must be >0 and <=sp_params.otp_num.
+ * @param handler OTP warning handler
+ * @param user value to pass to handler
  * @param pg pending group
  * @param pg pending group
  * @return 1 on success, 0 on failure
  * @return 1 on success, 0 on failure
  */
  */
-int SPProtoEncoder_Init (SPProtoEncoder *o, PacketRecvInterface *input, struct spproto_security_params sp_params, BPendingGroup *pg) WARN_UNUSED;
+int SPProtoEncoder_Init (SPProtoEncoder *o, PacketRecvInterface *input, struct spproto_security_params sp_params, int otp_warning_count, SPProtoEncoder_handler handler, void *user, BPendingGroup *pg) WARN_UNUSED;
 
 
 /**
 /**
  * Frees the object.
  * Frees the object.
@@ -129,14 +144,4 @@ void SPProtoEncoder_SetOTPSeed (SPProtoEncoder *o, uint16_t seed_id, uint8_t *ke
  */
  */
 void SPProtoEncoder_RemoveOTPSeed (SPProtoEncoder *o);
 void SPProtoEncoder_RemoveOTPSeed (SPProtoEncoder *o);
 
 
-/**
- * Returns the number of OTPs used so far, or total number if
- * no seed has been set yet.
- * OTPs must be enabled.
- *
- * @param o the object
- * @return OTP position
- */
-int SPProtoEncoder_GetOTPPosition (SPProtoEncoder *o);
-
 #endif
 #endif

+ 2 - 1
protocol/fragmentproto.h

@@ -76,12 +76,13 @@ struct fragmentproto_chunk_header {
  * in a FragmentProto packet.
  * in a FragmentProto packet.
  * 
  * 
  * @param carrier_mtu MTU of the carrier, i.e. maximum length of FragmentProto packets. Must be >sizeof(struct fragmentproto_chunk_header).
  * @param carrier_mtu MTU of the carrier, i.e. maximum length of FragmentProto packets. Must be >sizeof(struct fragmentproto_chunk_header).
- * @param frame_mtu maximum frame size
+ * @param frame_mtu maximum frame size. Must be >=0.
  * @return maximum number of chunks needed. Will be >0.
  * @return maximum number of chunks needed. Will be >0.
  */
  */
 static int fragmentproto_max_chunks_for_frame (int carrier_mtu, int frame_mtu)
 static int fragmentproto_max_chunks_for_frame (int carrier_mtu, int frame_mtu)
 {
 {
     ASSERT(carrier_mtu > sizeof(struct fragmentproto_chunk_header))
     ASSERT(carrier_mtu > sizeof(struct fragmentproto_chunk_header))
+    ASSERT(frame_mtu >= 0)
     
     
     return (BDIVIDE_UP(frame_mtu, (carrier_mtu - sizeof(struct fragmentproto_chunk_header))) + 1);
     return (BDIVIDE_UP(frame_mtu, (carrier_mtu - sizeof(struct fragmentproto_chunk_header))) + 1);
 }
 }