Skip to content

Commit 4fe8bec

Browse files
committed
Adding optional sendFilter to GCDAsyncUdpSocket. This allows for customizable traffic shaping, bandwidth monitoring, router emulation, etc.
1 parent e94301f commit 4fe8bec

File tree

2 files changed

+411
-157
lines changed

2 files changed

+411
-157
lines changed

GCD/GCDAsyncUdpSocket.h

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,34 @@ typedef enum GCDAsyncUdpSocketError GCDAsyncUdpSocketError;
7979
**/
8080
typedef BOOL (^GCDAsyncUdpSocketReceiveFilterBlock)(NSData *data, NSData *address, id *context);
8181

82+
/**
83+
* You may optionally set a send filter for the socket.
84+
* A filter can provide several interesting possibilities:
85+
*
86+
* 1. Optional caching of resolved addresses for domain names.
87+
* The cache could later be consulted, resulting in fewer system calls to getaddrinfo.
88+
*
89+
* 2. Reusable modules of code for bandwidth monitoring.
90+
*
91+
* 3. Sometimes traffic shapers are needed to simulate real world environments.
92+
* A filter allows you to write custom code to simulate such environments.
93+
* The ability to code this yourself is especially helpful when your simulated environment
94+
* is more complicated than simple traffic shaping (e.g. simulating a cone port restricted router),
95+
* or the system tools to handle this aren't available (e.g. on a mobile device).
96+
*
97+
* @param data - The packet that was received.
98+
* @param address - The address the data was received from.
99+
* See utilities section for methods to extract info from address.
100+
* @param tag - The tag that was passed in the send method.
101+
*
102+
* @returns - YES if the packet should actually be sent over the socket.
103+
* NO if the packet should be silently dropped (not sent over the socket).
104+
*
105+
* Regardless of the return value, the delegate will be informed that the packet was successfully sent.
106+
*
107+
**/
108+
typedef BOOL (^GCDAsyncUdpSocketSendFilterBlock)(NSData *data, NSData *address, long tag);
109+
82110

83111
@interface GCDAsyncUdpSocket : NSObject
84112

@@ -546,6 +574,46 @@ typedef BOOL (^GCDAsyncUdpSocketReceiveFilterBlock)(NSData *data, NSData *addres
546574
**/
547575
- (void)sendData:(NSData *)data toAddress:(NSData *)remoteAddr withTimeout:(NSTimeInterval)timeout tag:(long)tag;
548576

577+
/**
578+
* You may optionally set a send filter for the socket.
579+
* A filter can provide several interesting possibilities:
580+
*
581+
* 1. Optional caching of resolved addresses for domain names.
582+
* The cache could later be consulted, resulting in fewer system calls to getaddrinfo.
583+
*
584+
* 2. Reusable modules of code for bandwidth monitoring.
585+
*
586+
* 3. Sometimes traffic shapers are needed to simulate real world environments.
587+
* A filter allows you to write custom code to simulate such environments.
588+
* The ability to code this yourself is especially helpful when your simulated environment
589+
* is more complicated than simple traffic shaping (e.g. simulating a cone port restricted router),
590+
* or the system tools to handle this aren't available (e.g. on a mobile device).
591+
*
592+
* For more information about GCDAsyncUdpSocketSendFilterBlock, see the documentation for its typedef.
593+
* To remove a previously set filter, invoke this method and pass a nil filterBlock and NULL filterQueue.
594+
*
595+
* Note: This method invokes setSendFilter:withQueue:isAsynchronous: (documented below),
596+
* passing YES for the isAsynchronous parameter.
597+
**/
598+
- (void)setSendFilter:(GCDAsyncUdpSocketSendFilterBlock)filterBlock withQueue:(dispatch_queue_t)filterQueue;
599+
600+
/**
601+
* The receive filter can be run via dispatch_async or dispatch_sync.
602+
* Most typical situations call for asynchronous operation.
603+
*
604+
* However, there are a few situations in which synchronous operation is preferred.
605+
* Such is the case when the filter is extremely minimal and fast.
606+
* This is because dispatch_sync is faster than dispatch_async.
607+
*
608+
* If you choose synchronous operation, be aware of possible deadlock conditions.
609+
* Since the socket queue is executing your block via dispatch_sync,
610+
* then you cannot perform any tasks which may invoke dispatch_sync on the socket queue.
611+
* For example, you can't query properties on the socket.
612+
**/
613+
- (void)setSendFilter:(GCDAsyncUdpSocketSendFilterBlock)filterBlock
614+
withQueue:(dispatch_queue_t)filterQueue
615+
isAsynchronous:(BOOL)isAsynchronous;
616+
549617
#pragma mark Receiving
550618

551619
/**

0 commit comments

Comments
 (0)