iPhone EDGE/3G network port range? Anybody know? - iphone

I am trying to access 61616 in my iPhone app and the SCReachability code indicates that I have a valid network, but I time out trying to write to 61616. Does anyone know:
A. If the iPhone EDGE/3G network has a limited port range or isn't allowed to connect to this port?
B. How I can check explicitly for access to this port. Here is my "is the network reachable" code (borrowed from Apple's examples), which checks for "foo.bar.com" but doesn't show how to check for "foo.bar.com:61616".
Any help is appreciated!
- (BOOL)isDataSourceAvailable{
static BOOL checkNetwork = YES;
BOOL _isDataSourceAvailable = NO;
if (checkNetwork) { // Since checking the reachability of a host can be expensive, cache the result and perform the reachability check once.
checkNetwork = NO;
Boolean success;
const char *host_name = "foo.bar.com";
SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(NULL, host_name);
SCNetworkReachabilityFlags flags;
success = SCNetworkReachabilityGetFlags(reachability, &flags);
_isDataSourceAvailable = success && (flags & kSCNetworkFlagsReachable) && !(flags & kSCNetworkFlagsConnectionRequired);
CFRelease(reachability);
}
return _isDataSourceAvailable;
}

The SCNetworkReachability API only checks whether the address can be routed to. Quoting the documentation:
"Reachability" reflects whether a data
packet, sent by an application into
the network stack, can leave the local
computer. Note that reachability does
not guarantee that the data packet
will actually be received by the host.
This has nothing to do with NAT or port restrictions. Routing is based on addresses - not on ports. So all you can find out (via SCNetworkReachability API) is whether you could (in theory) reach the machine's interface. It does not try to establish a connection on a certain port.
So in order to find out whether that service is reachable you will have to try and test yourself. Preferably when the SCNetworkReachability API tells you that a connection can be established. Just try to connect to the server on port 61616 and see whether you get a connection or a timeout. Proper timeout values and handling is crucial here.

This is something that varies a lot from not just carrier to carrier but from contract to contract. For example, here in the UK O2 restrict internet access only to web addresses (presumably ports 80 and 443 but I didn't check) for pay-as-you-go customers but allow more-or-less free access for people on a contract. (I would hope that it's a little more open for iPhone PAYG customers.)
I think the practical upshot of this is that you can't assume access to high ports everywhere in the world.
I'm not sure that there's a simple way to check that a particular port is open, probably your best option is to use a "reasonable" timeout. Of course, there are a number of reasons you might get the timeout so your error would have to be suitable vague.

If your iPhone is connected over EDGE/Mobile, it might be behind a NAT gateway thus you being unable to contact it. At least that's the case with T-Mobile Germany. The iPhone gets an RFC IP address by T-Mobile (172.16.x.x).
I would test it with the iPhone connected to your local WiFi net and -- if possible -- generally design the app in a way that the iPhone contacts a server and then the server can communicate with the phone.

Are you trying to contact your iPhone from an external machine?
That likely does not work. Usually the GPRS/EDGE/UMTS infrastructure blocks incoming connections. Otherwise a mobile subscriber could be billed for unwanted traffic he did not request. (Imagine someone pinging your iPhone once per second for the next six weeks. You would pay for that...)
Solution is to establish a connection from the mobile device to the remote machine and then let the remote machine use that for traffic.

Related

ios/objective C ip spoofing sample

Does anyone know if there's a way to do IP spoofing in an ios/objectiveC/iphone app? I looked online, but couldn't find any way to do this. A few apps on the app store claim to be able to do this, but there is no indication anywhere as to how.
In order to modify an IP header, you need access to what's known as "raw sockets". Raw sockets aren't allowed on most operating system without elevated privileges.
Unfortunately for you, iOS apps don't run with the required privilege for raw sockets. You might be able to do something like this from the simulator running as root, using low level C sockets:
int sockfd = socket(AF_INET, SOCK_RAW, 0);
But you'll get an error if you try to run this on an iOS device (not jailbroken).
Spoofing an IP address has very limited use anyway. When you send data to a server from a spoofed IP address, you never see the response. Using a spoofed IP address, you'll never be able to establish any connection that requires any kind of handshake, including TCP and VPN connections.
About the best use of a spoofed IP address is to perform some kind of denial of service (DOS) attack, hiding your actual attack origin. You could perform a SYN flood, or you could flood UDP services such as DNS. However, you couldn't use it to post to a web server because HTTP requires a TCP connection.
More and more networks are getting smart and not forwarding traffic that doesn't originate from their network, so as time passes, these kinds of attacks will become less practical.

Possible to send data between two iOS devices?

I've read tons of questions about this all over the web, and can't seem to find a solid answer. If I have an iPhone that's running on cellular data and another iOS device on wifi (in two separate locations), is it possible for them to send data to each other directly without sending it first to a web server, then retrieving it? Are the only options sending and receiving from a server/Apple's iCloud? What if I knew the devices' ip addresses? Note that the iPhone has WiFi disabled.
I'm not looking to put this in the app store, it is for personal use. I know NSNotificationCenter isn't an option.
Using the gamekit framework you can send data between two iOS devices. It is easy to implement. Other than that I don't think there is any other way to send data between two iOS devices.
Actually, it IS possible. You may want to google for something called "UDP hole punching" or "TCP hole punching".
The main approach in short: Assuming you got something like a relay server, that is some server in the internet that is publicly addressable from every private LAN that is connected to the www. No you have your two clients A and B in (different) private LANs, with some Network address translation (NAT) going on, that want to establish a peer to peer connection.
First of all both will tell the server their IP address and the port they have in their own LAN. In the UDP or TCP packet, the server will find the public address and port of the device (or the NAT (router)). So the server knows the private and the public IP address as well as the ports.
If now A wants to communicate with B, it asks the server for help. The server will send a message to B that A wants to communicate with her telling her A's public and private IP and port. A gets back B's public and private information and port.
Now here is where the magic happens. Both clients now send packets out to establish a connection simultaneously to the private and public addresses of the other party and thus punching a whole in their NATs such that incoming connections will not be blocked. Even if one party's connection establishing packets will arrive before this whole is created, the other's packets will get through to such that a connection can be created.
Beware of some NATs that scan the data for IP addresses and translate them as well, but if you encrypt your data or change the appearance of the address (complement, ...) you will be fine.
Now the master question, how can the server communicate with one of the clients without an active connection. Well in this case you can use "connection reversal" and apple's "push notifications". Use the "push notifications" (pn) to tell a client behind a NAT that there is something of interest going on and that it should contact the server. Once it has done that the connection is active and can be used in the previous described fashion.
I hope this helps some people that get to this problem although the post is quite old!
You can only use direct IP address communications if the IP address are publicly reachable IP addresses accessible over the internet, and they are static (enough) so that they are not changing on you regularly as devices get assigned to addresses dynamically. In many (most) cases, that won't be true because your devices will be assigned their IP address dynamically and those addresses are frequently going to be self-assigned IP addresses that aren't publicly addressable.
As others have commented, using Apple-provided mechanisms like iCloud are probably the easiest options. If that's not something you'd like to entertain, there are probably ways to make use of a dynamic DNS service like DynDNS to manage the actual IP addresses of your devices. With something like that you might be able to use a direct IP connection between devices based on a named DNS lookup. You'd probably have to jump through some hoops to make that happen though and I'm not sure you'd want to go to that extent.
I think that Bluetooth would be a good option for you

iPhone - Peer to Peer connection over the internet

I am building an app that uses a async socket connection with a web server.
For sending large amounts of data I would like to connect two iPhones into a Peer to Peer connection using an async socket. I am more familiar with GCDAsyncSocket than to the iOS SDK socket API.
I have done something similar, but only within a local network were I would user NSNetService to publish a presence and get the addresses needed from the p2p connection.
Can you give me a hint on how to connect two iPhone over the internet using a p2p socket connection?
I do not know much about NSNetService but it seems that it only works in a local network. If you want to establish a p2p connection from an iphone to another you will always have the problem of several NATs (Network address translators) in your route. How to find the address and route to the peer? And how to get trough all the firewalls and NATs?
I am working on an app that needs to deal with the same problem and I have answered a similar question before which I will cite here:
Actually, it IS possible. You may want to google for something called
"UDP hole punching" or "TCP hole punching".
The main approach in short: Assuming you got something like a relay
server, that is some server in the internet that is publicly
addressable from every private LAN that is connected to the www. No
you have your two clients A and B in (different) private LANs, with
some Network address translation (NAT) going on, that want to
establish a peer to peer connection.
First of all both will tell the server their IP address and the port
they have in their own LAN. In the UDP or TCP packet, the server will
find the public address and port of the device (or the NAT (router)).
So the server knows the private and the public IP address as well as
the ports.
If now A wants to communicate with B, it asks the server for help. The
server will send a message to B that A wants to communicate with her
telling her A's public and private IP and port. A gets back B's public
and private information and port.
Now here is where the magic happens. Both clients now send packets out
to establish a connection simultaneously to the private and public
addresses of the other party and thus punching a whole in their NATs
such that incoming connections will not be blocked. Even if one
party's connection establishing packets will arrive before this whole
is created, the other's packets will get through to such that a
connection can be created.
Beware of some NATs that scan the data for IP addresses and translate
them as well, but if you encrypt your data or change the appearance of
the address (complement, ...) you will be fine.
Now the master question, how can the server communicate with one of
the clients without an active connection. Well in this case you can
use "connection reversal" and apple's "push notifications". Use the
"push notifications" (pn) to tell a client behind a NAT that there is
something of interest going on and that it should contact the server.
Once it has done that the connection is active and can be used in the
previous described fashion.
I hope this helps some people that get to this problem although the
post is quite old!
Now if you find this solution helpful and you try to implement it, please tell me if you are successful in getting the public ip and port of the server-client connection on the server side. You can also answer my question about this on stackoverflow.
Please be specific, u may use GCDAsyncSocket to connect 2 phones, u may use sample code from Github.

How can I find out whether I can be seen from outside in my iPhone App?

Using services like http://canyouseeme.org/ one can find out whether a particular port is open and his (public) IP is reachable from outside world.
Assuming I have my (expected) public IP and port, is there some easier or more reliable way to check my reachability than e.g. calling canyouseeme.org ?
iPhone's don't have a public IP (as far as I know).
Using 3G coverage you get allocated a local IP on your networks WAN.
Using WiFi you get allocated a local IP from your router.
Therefore I doubt you'll ever be able to truly identify your iPhone using an IP you think is associated with it (but probably isn't)

(iphone) reachability test for specific ip/port?

I've looked at Reachability sample from apple and another sample from "Iphone developer's cook book"
Here are steps to test ip/port reachability
construct sockaddr_in variable with given ip/port.
call SCNetworkReachabilityCreateWithAddress with the address
call SCNetworkReachabilityGetFlags and see if kSCNetworkFlagsReachable is set.
I find that whatever valid(valid-range) ip/port I put to test, my code says it's reachable even though they are not actually reachable when i ping or telnet test.
(I have seen other SO posts where reachability test to specific ip always succeed)
Reachability reachabilityWithAddress does not work
is SCNetworkReachability.. call only checks the validity of argument(ip address or hostname)? ie, do they actually send a packet(or do connect) to the given address to test reachability?
I can implement the async connect with timeout myself, but it's subtle matter how long the timeout should be not to be rejected by apple reviewers.(I am worried if it takes too long, apple reviewers might think my app is not handling network reachability at all)
Thank you
To answer your question based on the comments above, according to the SCNetworkReachability Reference
A remote host is considered reachable
when a data packet, sent by an
application into the network stack,
can leave the local device.
Reachability does not guarantee that
the data packet will actually be
received by the host.
This will not be able to check the status of your server but just make sure it can get a data packet out.
Apple wants for your app to elegantly fail if there are any network related issue, checking to see if internet is available using Reachability is the first step. If Reachability fails you can assume that you wont be able a server and alert the user immediately. The next steps are to properly handle errors returned by your server such as a 400 bad request, 404 file not found, setting a reasonable timeout, and not blocking the UI during long downloads while showing some sort of status indicator.