Skip to content
Browse files

Extract pinger to its own CocoaPods-compatible project

  • Loading branch information...
1 parent b9a5234 commit 29dd2bfbb94af06738d88c9b23efad8b34ac9610 @cdzombak committed Mar 12, 2013
View
1 Podfile
@@ -7,3 +7,4 @@ pod 'ODRefreshControl'
pod 'ZBarSDK'
pod 'iRate'
pod 'QuincyKit'
+pod 'CDZPinger', :podspec => 'https://raw.github.com/cdzombak/CDZPinger/master/CDZPinger.podspec'
View
7 Podfile.lock
@@ -1,6 +1,7 @@
PODS:
- AFNetworking (1.0.1)
+- CDZPinger (1.0)
- KissXML (5.0)
- MBProgressHUD (0.5)
- ODRefreshControl (1.1.0)
@@ -10,15 +11,21 @@ PODS:
DEPENDENCIES:
- AFNetworking
+- CDZPinger (from `https://raw.github.com/cdzombak/CDZPinger/master/CDZPinger.podspec')
- KissXML
- MBProgressHUD
- ODRefreshControl
- QuincyKit
- ZBarSDK
- iRate
+EXTERNAL SOURCES:
+ CDZPinger:
+ :podspec: https://raw.github.com/cdzombak/CDZPinger/master/CDZPinger.podspec
+
SPEC CHECKSUMS:
AFNetworking: 0bce3ae41023e080e96b8a2e0d07c94709f72a81
+ CDZPinger: 90f5eb629f26b780d08a3359ba4d504896359fbb
KissXML: 8dfe0fb6d4e987fec63656ff07d5e697f49976f8
MBProgressHUD: b23ee11c42253d6d804e8e0bfabdc334e8b2571f
ODRefreshControl: 886e323a7c25114b9e5c397a9eefbebc034224a9
View
22 buyvmmanager.xcodeproj/project.pbxproj
@@ -23,9 +23,6 @@
932709F3168244E20013DEB5 /* BVMServerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 932709F2168244E20013DEB5 /* BVMServerViewController.m */; };
93270A02168269740013DEB5 /* NSArray+BVMArrayExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = 93270A01168269740013DEB5 /* NSArray+BVMArrayExtensions.m */; };
93270A051682726F0013DEB5 /* BVMHumanValueTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 93270A041682726F0013DEB5 /* BVMHumanValueTransformer.m */; };
- 93270A14168279E60013DEB5 /* BVMPinger.m in Sources */ = {isa = PBXBuildFile; fileRef = 93270A13168279E60013DEB5 /* BVMPinger.m */; };
- 93270A1B16827E640013DEB5 /* SimplePing.m in Sources */ = {isa = PBXBuildFile; fileRef = 93270A1A16827E640013DEB5 /* SimplePing.m */; };
- 93270A1D16827E940013DEB5 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 93270A1C16827E940013DEB5 /* CFNetwork.framework */; };
935FEEC216829B4700BE3892 /* BVMIPListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 935FEEC116829B4700BE3892 /* BVMIPListViewController.m */; };
935FEEC61682A0FA00BE3892 /* BVMSizesListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 935FEEC51682A0FA00BE3892 /* BVMSizesListViewController.m */; };
935FEED11682BC3700BE3892 /* BVMServersManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 935FEED01682BC3700BE3892 /* BVMServersManager.m */; };
@@ -90,10 +87,6 @@
93270A01168269740013DEB5 /* NSArray+BVMArrayExtensions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+BVMArrayExtensions.m"; sourceTree = "<group>"; };
93270A031682726F0013DEB5 /* BVMHumanValueTransformer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BVMHumanValueTransformer.h; sourceTree = "<group>"; };
93270A041682726F0013DEB5 /* BVMHumanValueTransformer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BVMHumanValueTransformer.m; sourceTree = "<group>"; };
- 93270A12168279E60013DEB5 /* BVMPinger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BVMPinger.h; sourceTree = "<group>"; };
- 93270A13168279E60013DEB5 /* BVMPinger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BVMPinger.m; sourceTree = "<group>"; };
- 93270A1916827E640013DEB5 /* SimplePing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SimplePing.h; sourceTree = "<group>"; };
- 93270A1A16827E640013DEB5 /* SimplePing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SimplePing.m; sourceTree = "<group>"; };
93270A1C16827E940013DEB5 /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; };
935FEEC016829B4700BE3892 /* BVMIPListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BVMIPListViewController.h; sourceTree = "<group>"; };
935FEEC116829B4700BE3892 /* BVMIPListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BVMIPListViewController.m; sourceTree = "<group>"; };
@@ -155,7 +148,6 @@
files = (
93ADFEDF168EBC8E00F8256C /* Security.framework in Frameworks */,
9382EEAB1684F0200032E864 /* SystemConfiguration.framework in Frameworks */,
- 93270A1D16827E940013DEB5 /* CFNetwork.framework in Frameworks */,
932709BC1682353E0013DEB5 /* UIKit.framework in Frameworks */,
932709BE1682353E0013DEB5 /* Foundation.framework in Frameworks */,
932709C01682353E0013DEB5 /* CoreGraphics.framework in Frameworks */,
@@ -203,7 +195,6 @@
children = (
932709E616823FA20013DEB5 /* API */,
932709FE168269380013DEB5 /* Categories */,
- 93270A0E1682797A0013DEB5 /* Ping */,
935FEEDB1682CC2900BE3892 /* Views */,
932709F0168244710013DEB5 /* View Controllers */,
932709CA1682353E0013DEB5 /* BVMAppDelegate.h */,
@@ -303,17 +294,6 @@
name = Categories;
sourceTree = "<group>";
};
- 93270A0E1682797A0013DEB5 /* Ping */ = {
- isa = PBXGroup;
- children = (
- 93270A12168279E60013DEB5 /* BVMPinger.h */,
- 93270A13168279E60013DEB5 /* BVMPinger.m */,
- 93270A1916827E640013DEB5 /* SimplePing.h */,
- 93270A1A16827E640013DEB5 /* SimplePing.m */,
- );
- name = Ping;
- sourceTree = "<group>";
- };
935FEEDB1682CC2900BE3892 /* Views */ = {
isa = PBXGroup;
children = (
@@ -452,8 +432,6 @@
932709F3168244E20013DEB5 /* BVMServerViewController.m in Sources */,
93270A02168269740013DEB5 /* NSArray+BVMArrayExtensions.m in Sources */,
93270A051682726F0013DEB5 /* BVMHumanValueTransformer.m in Sources */,
- 93270A14168279E60013DEB5 /* BVMPinger.m in Sources */,
- 93270A1B16827E640013DEB5 /* SimplePing.m in Sources */,
935FEEC216829B4700BE3892 /* BVMIPListViewController.m in Sources */,
935FEEC61682A0FA00BE3892 /* BVMSizesListViewController.m in Sources */,
935FEED11682BC3700BE3892 /* BVMServersManager.m in Sources */,
View
29 buyvmmanager/BVMPinger.h
@@ -1,29 +0,0 @@
-#import <Foundation/Foundation.h>
-
-@protocol BVMPingerDelegate;
-
-@interface BVMPinger : NSObject
-
-@property (nonatomic, weak) id<BVMPingerDelegate> delegate;
-@property (nonatomic, copy, readonly) NSString *domainOrIp;
-
-- (id)initWithHost:(NSString *)domainOrIp;
-
-- (void)startPinging;
-- (void)stopPinging;
-
-@end
-
-@protocol BVMPingerDelegate <NSObject>
-
-- (void)pinger:(BVMPinger *)pinger didUpdateWithAverageSeconds:(double)seconds;
-
-@optional
-
-/**
- *
- * note: Pinger stops when an error is encountered
- */
-- (void)pinger:(BVMPinger *)pinger didEncounterError:(NSError *)error;
-
-@end
View
138 buyvmmanager/BVMPinger.m
@@ -1,138 +0,0 @@
-#import "BVMPinger.h"
-#import "SimplePing.h"
-
-static const NSTimeInterval kBVMPingWaitTime = 1.0;
-static const NSUInteger kBVMAverageNumberOfPings = 6;
-
-@interface BVMPinger () <SimplePingDelegate>
-
-@property (nonatomic, strong) SimplePing *simplePing;
-@property (nonatomic, copy) NSString *domainOrIp;
-
-@property (nonatomic, assign) BOOL pingingDesired;
-
-@property (nonatomic, strong) NSDate *pingStartTime;
-@property (nonatomic, strong, readonly) NSMutableArray *lastPingTimes;
-
-@end
-
-@implementation BVMPinger
-
-@synthesize lastPingTimes = _lastPingTimes;
-
-- (id)initWithHost:(NSString *)domainOrIp
-{
- self = [super init];
- if (self) {
- self.simplePing.delegate = self;
- self.domainOrIp = domainOrIp;
- }
- return self;
-}
-
-- (void)startPinging
-{
- if (!self.pingingDesired && !self.simplePing) {
- self.pingingDesired = YES;
- self.simplePing = [SimplePing simplePingWithHostName:self.domainOrIp];
- self.simplePing.delegate = self;
- [self.simplePing start];
- }
-}
-
-- (void)stopPinging
-{
- self.pingingDesired = NO;
- [self.simplePing stop];
- self.simplePing = nil;
-}
-
-- (void)receivedError:(NSError *)error {
- [self stopPinging];
-
- id delegate = self.delegate;
- if ([delegate respondsToSelector:@selector(pinger:didEncounterError:)]) {
- [delegate pinger:self didEncounterError:error];
- }
-}
-
-- (void)receivedPingWithTime:(NSTimeInterval)time {
- if (self.pingingDesired) {
- double delayInSeconds = kBVMPingWaitTime;
- dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
- dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
- [self sendPing];
- });
- }
-
- [self addPingTimeToRecord:time];
- __block NSTimeInterval totalTime = 0.0;
- __block NSUInteger timeCount = 0;
- [self.lastPingTimes enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
- totalTime += [obj doubleValue];
- timeCount++;
- }];
- NSTimeInterval averageTime = totalTime/(double)timeCount;
-
- id delegate = self.delegate;
- if ([delegate respondsToSelector:@selector(pinger:didUpdateWithAverageSeconds:)]) {
- [delegate pinger:self didUpdateWithAverageSeconds:averageTime];
- }
-}
-
-- (void)sendPing
-{
- [self.simplePing sendPingWithData:nil];
-}
-
-- (void)addPingTimeToRecord:(NSTimeInterval)time
-{
- if (self.lastPingTimes.count >= kBVMAverageNumberOfPings) {
- [self.lastPingTimes removeObjectAtIndex:0];
- }
- [self.lastPingTimes addObject:@(time)];
-}
-
-#pragma mark SimplePingDelegate methods
-
-- (void)simplePing:(SimplePing *)pinger didStartWithAddress:(NSData *)address
-{
- if (self.pingingDesired) [self sendPing];
-}
-
-- (void)simplePing:(SimplePing *)pinger didSendPacket:(NSData *)packet
-{
- self.pingStartTime = [NSDate date];
-
- NSLog(@"#%u sent", (unsigned int) OSSwapBigToHostInt16(((const ICMPHeader *) [packet bytes])->sequenceNumber));
-}
-
-- (void)simplePing:(SimplePing *)pinger didReceivePingResponsePacket:(NSData *)packet
-{
- NSTimeInterval pingTime = [[NSDate date] timeIntervalSinceDate:self.pingStartTime];
- [self receivedPingWithTime:pingTime];
-
- NSLog(@"#%u received", (unsigned int) OSSwapBigToHostInt16([SimplePing icmpInPacket:packet]->sequenceNumber) );
-}
-
-- (void)simplePing:(SimplePing *)pinger didFailWithError:(NSError *)error
-{
- [self receivedError:error];
-}
-
-- (void)simplePing:(SimplePing *)pinger didFailToSendPacket:(NSData *)packet error:(NSError *)error
-{
- [self receivedError:error];
-}
-
-#pragma mark Property overrides
-
-- (NSMutableArray *)lastPingTimes
-{
- if (!_lastPingTimes) {
- _lastPingTimes = [NSMutableArray array];
- }
- return _lastPingTimes;
-}
-
-@end
View
16 buyvmmanager/BVMServerViewController.m
@@ -1,7 +1,7 @@
#import "BVMServerViewController.h"
#import "BVMServerInfo.h"
#import "BVMServerActionPerform.h"
-#import "BVMPinger.h"
+#import "CDZPinger.h"
#import "BVMHumanValueTransformer.h"
#import "BVMIPListViewController.h"
#import "BVMSizesListViewController.h"
@@ -45,14 +45,14 @@ typedef NS_ENUM(NSUInteger, BVMServerTableViewActionRows) {
}
}
-@interface BVMServerViewController () <BVMPingerDelegate>
+@interface BVMServerViewController () <CDZPingerDelegate>
@property (nonatomic, copy) NSString *serverId;
@property (nonatomic, copy) NSString *serverName;
@property (nonatomic, strong) BVMServerInfo *serverInfo;
@property (nonatomic, copy) NSString *pingString;
-@property (nonatomic, strong) BVMPinger *pinger;
+@property (nonatomic, strong) CDZPinger *pinger;
@property (nonatomic, strong) UIView *headerView;
@property (nonatomic, strong) UILabel *headerHostnameLabel;
@@ -185,9 +185,9 @@ - (void)refreshHeaderView
}
}
-#pragma mark BVMPingerDelegate methods
+#pragma mark CDZPingerDelegate methods
-- (void)pinger:(BVMPinger *)pinger didUpdateWithAverageSeconds:(double)seconds
+- (void)pinger:(CDZPinger *)pinger didUpdateWithAverageSeconds:(NSTimeInterval)seconds
{
self.pingString = [NSString stringWithFormat:@"%.f ms", seconds*1000];
@@ -197,7 +197,7 @@ - (void)pinger:(BVMPinger *)pinger didUpdateWithAverageSeconds:(double)seconds
[self.tableView endUpdates];
}
-- (void)pinger:(BVMPinger *)pinger didEncounterError:(NSError *)error
+- (void)pinger:(CDZPinger *)pinger didEncounterError:(NSError *)error
{
if (pinger != self.pinger) return;
@@ -581,10 +581,10 @@ - (UIView *)headerView {
return _headerView;
}
-- (BVMPinger *)pinger
+- (CDZPinger *)pinger
{
if (!_pinger) {
- _pinger = [[BVMPinger alloc] initWithHost:self.serverInfo.mainIpAddress];
+ _pinger = [[CDZPinger alloc] initWithHost:self.serverInfo.mainIpAddress];
_pinger.delegate = self;
}
return _pinger;
View
196 buyvmmanager/SimplePing.h
@@ -1,196 +0,0 @@
-/*
- File: SimplePing.h
-
- Contains: Implements ping.
-
- Written by: DTS
-
- Copyright: Copyright (c) 2010-2012 Apple Inc. All Rights Reserved.
-
- Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc.
- ("Apple") in consideration of your agreement to the following
- terms, and your use, installation, modification or
- redistribution of this Apple software constitutes acceptance of
- these terms. If you do not agree with these terms, please do
- not use, install, modify or redistribute this Apple software.
-
- In consideration of your agreement to abide by the following
- terms, and subject to these terms, Apple grants you a personal,
- non-exclusive license, under Apple's copyrights in this
- original Apple software (the "Apple Software"), to use,
- reproduce, modify and redistribute the Apple Software, with or
- without modifications, in source and/or binary forms; provided
- that if you redistribute the Apple Software in its entirety and
- without modifications, you must retain this notice and the
- following text and disclaimers in all such redistributions of
- the Apple Software. Neither the name, trademarks, service marks
- or logos of Apple Inc. may be used to endorse or promote
- products derived from the Apple Software without specific prior
- written permission from Apple. Except as expressly stated in
- this notice, no other rights or licenses, express or implied,
- are granted by Apple herein, including but not limited to any
- patent rights that may be infringed by your derivative works or
- by other works in which the Apple Software may be incorporated.
-
- The Apple Software is provided by Apple on an "AS IS" basis.
- APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
- WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT,
- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING
- THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
- COMBINATION WITH YOUR PRODUCTS.
-
- IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT,
- INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY
- OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
- OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY
- OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR
- OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
-
-*/
-
-#import <Foundation/Foundation.h>
-
-#if TARGET_OS_EMBEDDED || TARGET_IPHONE_SIMULATOR
- #import <CFNetwork/CFNetwork.h>
-#else
- #import <CoreServices/CoreServices.h>
-#endif
-
-#include <AssertMacros.h>
-
-#pragma mark * SimplePing
-
-// The SimplePing class is a very simple class that lets you send and receive pings.
-
-@protocol SimplePingDelegate;
-
-@interface SimplePing : NSObject
-
-+ (SimplePing *)simplePingWithHostName:(NSString *)hostName; // chooses first IPv4 address
-+ (SimplePing *)simplePingWithHostAddress:(NSData *)hostAddress; // contains (struct sockaddr)
-
-@property (nonatomic, weak, readwrite) id<SimplePingDelegate> delegate;
-
-@property (nonatomic, copy, readonly ) NSString * hostName;
-@property (nonatomic, copy, readonly ) NSData * hostAddress;
-@property (nonatomic, assign, readonly ) uint16_t identifier;
-@property (nonatomic, assign, readonly ) uint16_t nextSequenceNumber;
-
-- (void)start;
- // Starts the pinger object pinging. You should call this after
- // you've setup the delegate and any ping parameters.
-
-- (void)sendPingWithData:(NSData *)data;
- // Sends an actual ping. Pass nil for data to use a standard 56 byte payload (resulting in a
- // standard 64 byte ping). Otherwise pass a non-nil value and it will be appended to the
- // ICMP header.
- //
- // Do not try to send a ping before you receive the -simplePing:didStartWithAddress: delegate
- // callback.
-
-- (void)stop;
- // Stops the pinger object. You should call this when you're done
- // pinging.
-
-+ (const struct ICMPHeader *)icmpInPacket:(NSData *)packet;
- // Given a valid IP packet contains an ICMP , returns the address of the ICMP header that
- // follows the IP header. This doesn't do any significant validation of the packet.
-
-@end
-
-@protocol SimplePingDelegate <NSObject>
-
-@optional
-
-- (void)simplePing:(SimplePing *)pinger didStartWithAddress:(NSData *)address;
- // Called after the SimplePing has successfully started up. After this callback, you
- // can start sending pings via -sendPingWithData:
-
-- (void)simplePing:(SimplePing *)pinger didFailWithError:(NSError *)error;
- // If this is called, the SimplePing object has failed. By the time this callback is
- // called, the object has stopped (that is, you don't need to call -stop yourself).
-
-// IMPORTANT: On the send side the packet does not include an IP header.
-// On the receive side, it does. In that case, use +[SimplePing icmpInPacket:]
-// to find the ICMP header within the packet.
-
-- (void)simplePing:(SimplePing *)pinger didSendPacket:(NSData *)packet;
- // Called whenever the SimplePing object has successfully sent a ping packet.
-
-- (void)simplePing:(SimplePing *)pinger didFailToSendPacket:(NSData *)packet error:(NSError *)error;
- // Called whenever the SimplePing object tries and fails to send a ping packet.
-
-- (void)simplePing:(SimplePing *)pinger didReceivePingResponsePacket:(NSData *)packet;
- // Called whenever the SimplePing object receives an ICMP packet that looks like
- // a response to one of our pings (that is, has a valid ICMP checksum, has
- // an identifier that matches our identifier, and has a sequence number in
- // the range of sequence numbers that we've sent out).
-
-- (void)simplePing:(SimplePing *)pinger didReceiveUnexpectedPacket:(NSData *)packet;
- // Called whenever the SimplePing object receives an ICMP packet that does not
- // look like a response to one of our pings.
-
-@end
-
-#pragma mark * IP and ICMP On-The-Wire Format
-
-// The following declarations specify the structure of ping packets on the wire.
-
-// IP header structure:
-
-struct IPHeader {
- uint8_t versionAndHeaderLength;
- uint8_t differentiatedServices;
- uint16_t totalLength;
- uint16_t identification;
- uint16_t flagsAndFragmentOffset;
- uint8_t timeToLive;
- uint8_t protocol;
- uint16_t headerChecksum;
- uint8_t sourceAddress[4];
- uint8_t destinationAddress[4];
- // options...
- // data...
-};
-typedef struct IPHeader IPHeader;
-
-check_compile_time(sizeof(IPHeader) == 20);
-check_compile_time(offsetof(IPHeader, versionAndHeaderLength) == 0);
-check_compile_time(offsetof(IPHeader, differentiatedServices) == 1);
-check_compile_time(offsetof(IPHeader, totalLength) == 2);
-check_compile_time(offsetof(IPHeader, identification) == 4);
-check_compile_time(offsetof(IPHeader, flagsAndFragmentOffset) == 6);
-check_compile_time(offsetof(IPHeader, timeToLive) == 8);
-check_compile_time(offsetof(IPHeader, protocol) == 9);
-check_compile_time(offsetof(IPHeader, headerChecksum) == 10);
-check_compile_time(offsetof(IPHeader, sourceAddress) == 12);
-check_compile_time(offsetof(IPHeader, destinationAddress) == 16);
-
-// ICMP type and code combinations:
-
-enum {
- kICMPTypeEchoReply = 0, // code is always 0
- kICMPTypeEchoRequest = 8 // code is always 0
-};
-
-// ICMP header structure:
-
-struct ICMPHeader {
- uint8_t type;
- uint8_t code;
- uint16_t checksum;
- uint16_t identifier;
- uint16_t sequenceNumber;
- // data...
-};
-typedef struct ICMPHeader ICMPHeader;
-
-check_compile_time(sizeof(ICMPHeader) == 8);
-check_compile_time(offsetof(ICMPHeader, type) == 0);
-check_compile_time(offsetof(ICMPHeader, code) == 1);
-check_compile_time(offsetof(ICMPHeader, checksum) == 2);
-check_compile_time(offsetof(ICMPHeader, identifier) == 4);
-check_compile_time(offsetof(ICMPHeader, sequenceNumber) == 6);
View
627 buyvmmanager/SimplePing.m
@@ -1,627 +0,0 @@
-/*
- File: SimplePing.m
-
- Contains: Implements ping.
-
- Written by: DTS
-
- Copyright: Copyright (c) 2010-2012 Apple Inc. All Rights Reserved.
-
- Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc.
- ("Apple") in consideration of your agreement to the following
- terms, and your use, installation, modification or
- redistribution of this Apple software constitutes acceptance of
- these terms. If you do not agree with these terms, please do
- not use, install, modify or redistribute this Apple software.
-
- In consideration of your agreement to abide by the following
- terms, and subject to these terms, Apple grants you a personal,
- non-exclusive license, under Apple's copyrights in this
- original Apple software (the "Apple Software"), to use,
- reproduce, modify and redistribute the Apple Software, with or
- without modifications, in source and/or binary forms; provided
- that if you redistribute the Apple Software in its entirety and
- without modifications, you must retain this notice and the
- following text and disclaimers in all such redistributions of
- the Apple Software. Neither the name, trademarks, service marks
- or logos of Apple Inc. may be used to endorse or promote
- products derived from the Apple Software without specific prior
- written permission from Apple. Except as expressly stated in
- this notice, no other rights or licenses, express or implied,
- are granted by Apple herein, including but not limited to any
- patent rights that may be infringed by your derivative works or
- by other works in which the Apple Software may be incorporated.
-
- The Apple Software is provided by Apple on an "AS IS" basis.
- APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
- WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT,
- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING
- THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
- COMBINATION WITH YOUR PRODUCTS.
-
- IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT,
- INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY
- OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
- OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY
- OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR
- OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
-
-*/
-
-#import "SimplePing.h"
-
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <errno.h>
-
-#pragma mark * ICMP On-The-Wire Format
-
-static uint16_t in_cksum(const void *buffer, size_t bufferLen)
- // This is the standard BSD checksum code, modified to use modern types.
-{
- size_t bytesLeft;
- int32_t sum;
- const uint16_t * cursor;
- union {
- uint16_t us;
- uint8_t uc[2];
- } last;
- uint16_t answer;
-
- bytesLeft = bufferLen;
- sum = 0;
- cursor = buffer;
-
- /*
- * Our algorithm is simple, using a 32 bit accumulator (sum), we add
- * sequential 16 bit words to it, and at the end, fold back all the
- * carry bits from the top 16 bits into the lower 16 bits.
- */
- while (bytesLeft > 1) {
- sum += *cursor;
- cursor += 1;
- bytesLeft -= 2;
- }
-
- /* mop up an odd byte, if necessary */
- if (bytesLeft == 1) {
- last.uc[0] = * (const uint8_t *) cursor;
- last.uc[1] = 0;
- sum += last.us;
- }
-
- /* add back carry outs from top 16 bits to low 16 bits */
- sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
- sum += (sum >> 16); /* add carry */
- answer = (uint16_t) ~sum; /* truncate to 16 bits */
-
- return answer;
-}
-
-#pragma mark * SimplePing
-
-@interface SimplePing ()
-
-@property (nonatomic, copy, readwrite) NSData * hostAddress;
-@property (nonatomic, assign, readwrite) uint16_t nextSequenceNumber;
-
-- (void)stopHostResolution;
-- (void)stopDataTransfer;
-
-@end
-
-@implementation SimplePing
-{
- CFHostRef _host;
- CFSocketRef _socket;
-}
-
-@synthesize hostName = _hostName;
-@synthesize hostAddress = _hostAddress;
-
-@synthesize delegate = _delegate;
-@synthesize identifier = _identifier;
-@synthesize nextSequenceNumber = _nextSequenceNumber;
-
-- (id)initWithHostName:(NSString *)hostName address:(NSData *)hostAddress
- // The initialiser common to both of our construction class methods.
-{
- assert( (hostName != nil) == (hostAddress == nil) );
- self = [super init];
- if (self != nil) {
- self->_hostName = [hostName copy];
- self->_hostAddress = [hostAddress copy];
- self->_identifier = (uint16_t) arc4random();
- }
- return self;
-}
-
-- (void)dealloc
-{
- // -stop takes care of _host and _socket.
- [self stop];
- assert(self->_host == NULL);
- assert(self->_socket == NULL);
-}
-
-+ (SimplePing *)simplePingWithHostName:(NSString *)hostName
- // See comment in header.
-{
- return [[SimplePing alloc] initWithHostName:hostName address:nil];
-}
-
-+ (SimplePing *)simplePingWithHostAddress:(NSData *)hostAddress
- // See comment in header.
-{
- return [[SimplePing alloc] initWithHostName:NULL address:hostAddress];
-}
-
-- (void)noop
-{
-}
-
-- (void)didFailWithError:(NSError *)error
- // Shut down the pinger object and tell the delegate about the error.
-{
- assert(error != nil);
-
- // We retain ourselves temporarily because it's common for the delegate method
- // to release its last reference to use, which causes -dealloc to be called here.
- // If we then reference self on the return path, things go badly. I don't think
- // that happens currently, but I've got into the habit of doing this as a
- // defensive measure.
-
- [self performSelector:@selector(noop) withObject:nil afterDelay:0.0];
-
- [self stop];
- if ( (self.delegate != nil) && [self.delegate respondsToSelector:@selector(simplePing:didFailWithError:)] ) {
- [self.delegate simplePing:self didFailWithError:error];
- }
-}
-
-- (void)didFailWithHostStreamError:(CFStreamError)streamError
- // Convert the CFStreamError to an NSError and then call through to
- // -didFailWithError: to shut down the pinger object and tell the
- // delegate about the error.
-{
- NSDictionary * userInfo;
- NSError * error;
-
- if (streamError.domain == kCFStreamErrorDomainNetDB) {
- userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
- [NSNumber numberWithInteger:streamError.error], kCFGetAddrInfoFailureKey,
- nil
- ];
- } else {
- userInfo = nil;
- }
- error = [NSError errorWithDomain:(NSString *)kCFErrorDomainCFNetwork code:kCFHostErrorUnknown userInfo:userInfo];
- assert(error != nil);
-
- [self didFailWithError:error];
-}
-
-- (void)sendPingWithData:(NSData *)data
- // See comment in header.
-{
- int err;
- NSData * payload;
- NSMutableData * packet;
- ICMPHeader * icmpPtr;
- ssize_t bytesSent;
-
- // Construct the ping packet.
-
- payload = data;
- if (payload == nil) {
- payload = [[NSString stringWithFormat:@"%28zd bottles of beer on the wall", (ssize_t) 99 - (size_t) (self.nextSequenceNumber % 100) ] dataUsingEncoding:NSASCIIStringEncoding];
- assert(payload != nil);
-
- assert([payload length] == 56);
- }
-
- packet = [NSMutableData dataWithLength:sizeof(*icmpPtr) + [payload length]];
- assert(packet != nil);
-
- icmpPtr = [packet mutableBytes];
- icmpPtr->type = kICMPTypeEchoRequest;
- icmpPtr->code = 0;
- icmpPtr->checksum = 0;
- icmpPtr->identifier = OSSwapHostToBigInt16(self.identifier);
- icmpPtr->sequenceNumber = OSSwapHostToBigInt16(self.nextSequenceNumber);
- memcpy(&icmpPtr[1], [payload bytes], [payload length]);
-
- // The IP checksum returns a 16-bit number that's already in correct byte order
- // (due to wacky 1's complement maths), so we just put it into the packet as a
- // 16-bit unit.
-
- icmpPtr->checksum = in_cksum([packet bytes], [packet length]);
-
- // Send the packet.
-
- if (self->_socket == NULL) {
- bytesSent = -1;
- err = EBADF;
- } else {
- bytesSent = sendto(
- CFSocketGetNative(self->_socket),
- [packet bytes],
- [packet length],
- 0,
- (struct sockaddr *) [self.hostAddress bytes],
- (socklen_t) [self.hostAddress length]
- );
- err = 0;
- if (bytesSent < 0) {
- err = errno;
- }
- }
-
- // Handle the results of the send.
-
- if ( (bytesSent > 0) && (((NSUInteger) bytesSent) == [packet length]) ) {
-
- // Complete success. Tell the client.
-
- if ( (self.delegate != nil) && [self.delegate respondsToSelector:@selector(simplePing:didSendPacket:)] ) {
- [self.delegate simplePing:self didSendPacket:packet];
- }
- } else {
- NSError * error;
-
- // Some sort of failure. Tell the client.
-
- if (err == 0) {
- err = ENOBUFS; // This is not a hugely descriptor error, alas.
- }
- error = [NSError errorWithDomain:NSPOSIXErrorDomain code:err userInfo:nil];
- if ( (self.delegate != nil) && [self.delegate respondsToSelector:@selector(simplePing:didFailToSendPacket:error:)] ) {
- [self.delegate simplePing:self didFailToSendPacket:packet error:error];
- }
- }
-
- self.nextSequenceNumber += 1;
-}
-
-+ (NSUInteger)icmpHeaderOffsetInPacket:(NSData *)packet
- // Returns the offset of the ICMPHeader within an IP packet.
-{
- NSUInteger result;
- const struct IPHeader * ipPtr;
- size_t ipHeaderLength;
-
- result = NSNotFound;
- if ([packet length] >= (sizeof(IPHeader) + sizeof(ICMPHeader))) {
- ipPtr = (const IPHeader *) [packet bytes];
- assert((ipPtr->versionAndHeaderLength & 0xF0) == 0x40); // IPv4
- assert(ipPtr->protocol == 1); // ICMP
- ipHeaderLength = (ipPtr->versionAndHeaderLength & 0x0F) * sizeof(uint32_t);
- if ([packet length] >= (ipHeaderLength + sizeof(ICMPHeader))) {
- result = ipHeaderLength;
- }
- }
- return result;
-}
-
-+ (const struct ICMPHeader *)icmpInPacket:(NSData *)packet
- // See comment in header.
-{
- const struct ICMPHeader * result;
- NSUInteger icmpHeaderOffset;
-
- result = nil;
- icmpHeaderOffset = [self icmpHeaderOffsetInPacket:packet];
- if (icmpHeaderOffset != NSNotFound) {
- result = (const struct ICMPHeader *) (((const uint8_t *)[packet bytes]) + icmpHeaderOffset);
- }
- return result;
-}
-
-- (BOOL)isValidPingResponsePacket:(NSMutableData *)packet
- // Returns true if the packet looks like a valid ping response packet destined
- // for us.
-{
- BOOL result;
- NSUInteger icmpHeaderOffset;
- ICMPHeader * icmpPtr;
- uint16_t receivedChecksum;
- uint16_t calculatedChecksum;
-
- result = NO;
-
- icmpHeaderOffset = [[self class] icmpHeaderOffsetInPacket:packet];
- if (icmpHeaderOffset != NSNotFound) {
- icmpPtr = (struct ICMPHeader *) (((uint8_t *)[packet mutableBytes]) + icmpHeaderOffset);
-
- receivedChecksum = icmpPtr->checksum;
- icmpPtr->checksum = 0;
- calculatedChecksum = in_cksum(icmpPtr, [packet length] - icmpHeaderOffset);
- icmpPtr->checksum = receivedChecksum;
-
- if (receivedChecksum == calculatedChecksum) {
- if ( (icmpPtr->type == kICMPTypeEchoReply) && (icmpPtr->code == 0) ) {
- if ( OSSwapBigToHostInt16(icmpPtr->identifier) == self.identifier ) {
- if ( OSSwapBigToHostInt16(icmpPtr->sequenceNumber) < self.nextSequenceNumber ) {
- result = YES;
- }
- }
- }
- }
- }
-
- return result;
-}
-
-- (void)readData
- // Called by the socket handling code (SocketReadCallback) to process an ICMP
- // messages waiting on the socket.
-{
- int err;
- struct sockaddr_storage addr;
- socklen_t addrLen;
- ssize_t bytesRead;
- void * buffer;
- enum { kBufferSize = 65535 };
-
- // 65535 is the maximum IP packet size, which seems like a reasonable bound
- // here (plus it's what <x-man-page://8/ping> uses).
-
- buffer = malloc(kBufferSize);
- assert(buffer != NULL);
-
- // Actually read the data.
-
- addrLen = sizeof(addr);
- bytesRead = recvfrom(CFSocketGetNative(self->_socket), buffer, kBufferSize, 0, (struct sockaddr *) &addr, &addrLen);
- err = 0;
- if (bytesRead < 0) {
- err = errno;
- }
-
- // Process the data we read.
-
- if (bytesRead > 0) {
- NSMutableData * packet;
-
- packet = [NSMutableData dataWithBytes:buffer length:(NSUInteger) bytesRead];
- assert(packet != nil);
-
- // We got some data, pass it up to our client.
-
- if ( [self isValidPingResponsePacket:packet] ) {
- if ( (self.delegate != nil) && [self.delegate respondsToSelector:@selector(simplePing:didReceivePingResponsePacket:)] ) {
- [self.delegate simplePing:self didReceivePingResponsePacket:packet];
- }
- } else {
- if ( (self.delegate != nil) && [self.delegate respondsToSelector:@selector(simplePing:didReceiveUnexpectedPacket:)] ) {
- [self.delegate simplePing:self didReceiveUnexpectedPacket:packet];
- }
- }
- } else {
-
- // We failed to read the data, so shut everything down.
-
- if (err == 0) {
- err = EPIPE;
- }
- [self didFailWithError:[NSError errorWithDomain:NSPOSIXErrorDomain code:err userInfo:nil]];
- }
-
- free(buffer);
-
- // Note that we don't loop back trying to read more data. Rather, we just
- // let CFSocket call us again.
-}
-
-static void SocketReadCallback(CFSocketRef s, CFSocketCallBackType type, CFDataRef address, const void *data, void *info)
- // This C routine is called by CFSocket when there's data waiting on our
- // ICMP socket. It just redirects the call to Objective-C code.
-{
- SimplePing * obj;
-
- obj = (__bridge SimplePing *) info;
- assert([obj isKindOfClass:[SimplePing class]]);
-
- #pragma unused(s)
- assert(s == obj->_socket);
- #pragma unused(type)
- assert(type == kCFSocketReadCallBack);
- #pragma unused(address)
- assert(address == nil);
- #pragma unused(data)
- assert(data == nil);
-
- [obj readData];
-}
-
-- (void)startWithHostAddress
- // We have a host address, so let's actually start pinging it.
-{
- int err;
- int fd;
- const struct sockaddr * addrPtr;
-
- assert(self.hostAddress != nil);
-
- // Open the socket.
-
- addrPtr = (const struct sockaddr *) [self.hostAddress bytes];
-
- fd = -1;
- err = 0;
- switch (addrPtr->sa_family) {
- case AF_INET: {
- fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP);
- if (fd < 0) {
- err = errno;
- }
- } break;
- case AF_INET6:
- assert(NO);
- // fall through
- default: {
- err = EPROTONOSUPPORT;
- } break;
- }
-
- if (err != 0) {
- [self didFailWithError:[NSError errorWithDomain:NSPOSIXErrorDomain code:err userInfo:nil]];
- } else {
- CFSocketContext context = {0, (__bridge void *)(self), NULL, NULL, NULL};
- CFRunLoopSourceRef rls;
-
- // Wrap it in a CFSocket and schedule it on the runloop.
-
- self->_socket = CFSocketCreateWithNative(NULL, fd, kCFSocketReadCallBack, SocketReadCallback, &context);
- assert(self->_socket != NULL);
-
- // The socket will now take care of cleaning up our file descriptor.
-
- assert( CFSocketGetSocketFlags(self->_socket) & kCFSocketCloseOnInvalidate );
- fd = -1;
-
- rls = CFSocketCreateRunLoopSource(NULL, self->_socket, 0);
- assert(rls != NULL);
-
- CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
-
- CFRelease(rls);
-
- if ( (self.delegate != nil) && [self.delegate respondsToSelector:@selector(simplePing:didStartWithAddress:)] ) {
- [self.delegate simplePing:self didStartWithAddress:self.hostAddress];
- }
- }
- assert(fd == -1);
-}
-
-- (void)hostResolutionDone
- // Called by our CFHost resolution callback (HostResolveCallback) when host
- // resolution is complete. We just latch the first IPv4 address and kick
- // off the pinging process.
-{
- Boolean resolved;
- NSArray * addresses;
-
- // Find the first IPv4 address.
-
- addresses = (__bridge NSArray *) CFHostGetAddressing(self->_host, &resolved);
- if ( resolved && (addresses != nil) ) {
- resolved = false;
- for (NSData * address in addresses) {
- const struct sockaddr * addrPtr;
-
- addrPtr = (const struct sockaddr *) [address bytes];
- if ( [address length] >= sizeof(struct sockaddr) && addrPtr->sa_family == AF_INET) {
- self.hostAddress = address;
- resolved = true;
- break;
- }
- }
- }
-
- // We're done resolving, so shut that down.
-
- [self stopHostResolution];
-
- // If all is OK, start pinging, otherwise shut down the pinger completely.
-
- if (resolved) {
- [self startWithHostAddress];
- } else {
- [self didFailWithError:[NSError errorWithDomain:(NSString *)kCFErrorDomainCFNetwork code:kCFHostErrorHostNotFound userInfo:nil]];
- }
-}
-
-static void HostResolveCallback(CFHostRef theHost, CFHostInfoType typeInfo, const CFStreamError *error, void *info)
- // This C routine is called by CFHost when the host resolution is complete.
- // It just redirects the call to the appropriate Objective-C method.
-{
- SimplePing * obj;
-
- NSLog(@">HostResolveCallback");
-
- obj = (__bridge SimplePing *) info;
- assert([obj isKindOfClass:[SimplePing class]]);
-
- #pragma unused(theHost)
- assert(theHost == obj->_host);
- #pragma unused(typeInfo)
- assert(typeInfo == kCFHostAddresses);
-
- if ( (error != NULL) && (error->domain != 0) ) {
- [obj didFailWithHostStreamError:*error];
- } else {
- [obj hostResolutionDone];
- }
-}
-
-- (void)start
- // See comment in header.
-{
- // If the user supplied us with an address, just start pinging that. Otherwise
- // start a host resolution.
-
- if (self->_hostAddress != nil) {
- [self startWithHostAddress];
- } else {
- Boolean success;
- CFHostClientContext context = {0, (__bridge void *)(self), NULL, NULL, NULL};
- CFStreamError streamError;
-
- assert(self->_host == NULL);
-
- self->_host = CFHostCreateWithName(NULL, (__bridge CFStringRef) self.hostName);
- assert(self->_host != NULL);
-
- CFHostSetClient(self->_host, HostResolveCallback, &context);
-
- CFHostScheduleWithRunLoop(self->_host, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
-
- NSLog(@">CFHostStartInfoResolution");
- success = CFHostStartInfoResolution(self->_host, kCFHostAddresses, &streamError);
- NSLog(@"<CFHostStartInfoResolution");
- if ( ! success ) {
- [self didFailWithHostStreamError:streamError];
- }
- }
-}
-
-- (void)stopHostResolution
- // Shut down the CFHost.
-{
- if (self->_host != NULL) {
- CFHostSetClient(self->_host, NULL, NULL);
- CFHostUnscheduleFromRunLoop(self->_host, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
- CFRelease(self->_host);
- self->_host = NULL;
- }
-}
-
-- (void)stopDataTransfer
- // Shut down anything to do with sending and receiving pings.
-{
- if (self->_socket != NULL) {
- CFSocketInvalidate(self->_socket);
- CFRelease(self->_socket);
- self->_socket = NULL;
- }
-}
-
-- (void)stop
- // See comment in header.
-{
- [self stopHostResolution];
- [self stopDataTransfer];
-
- // If we were started with a host name, junk the host address on stop. If the
- // client calls -start again, we'll re-resolve the host name.
-
- if (self.hostName != nil) {
- self.hostAddress = NULL;
- }
-}
-
-@end

0 comments on commit 29dd2bf

Please sign in to comment.
Something went wrong with that request. Please try again.