Discover a TCP/IP Socket? - sockets

I am using Objective-C and Java for this, but I think the question is language-neutral.
I have an iOS client that talks to a Java server over TCP/IP. Right now I need to tell at least one of the parties the IP address of the other. Is there a standard way that I can "discover" IP addresses (from one side or the other)?
Also, how would switching to UDP affect the answer?

There are many protocols for discovering other devices/servers on the network. One of the most commonly used in the iOS realm is "Bonjour". Look at Apple's sample apps.

Is there a standard way that I can "discover" IP addresses (from one side or the other)?
Yes, it's called "port sniffing" and will certainly get you in trouble since it's a common kind of attack.
You simply try all IP addresses in a range. Many firewall products will consider this an "intrusion" attempt and log you with the intrusion detection software.
We almost never "discover" addresses.
That's what "domain names" are for.

Why can't the server have a well known DNS name?

Related

Connect sockets directly after introduction through server

I'm looking for the name of a protocol and example code that permits handing off IP/port connections to establish unmediated P2P after introduction through a server.
Simple example:
You and I both start chat programs that connect to chatintroduce.com (fictional server). I send you a "Hi! Wanna chat?" message. It doesn't get sent. Instead my chat program tells chatintroduce to send your chat program a request for connection. You respond to a prompt and your chat program tells chatintroduce to broker the connection. Chatintroduce establishes an initial two-way connection between us. Now, this final step is important, chatintroduce releases control and our two chat programs now talk directly to each other without any traffic through chatintroduce.
In other words, I construct packets which have your IP address and you receive them without interference from firewalls, NATs or any other technologies. In other words, true peer-to-peer connection independent of intermediate server.
I need to know what search terms to use to find appropriate technology. An RFC name would suffice. I've been searching for days without success.
I think what you are looking for is TCP/UDP hole punching which typically coordinates the P2P connection using a STUN server to determine the "capabilities" of the firewalls (e.g. is it a full cone nat? symmetric?).
https://en.wikipedia.org/wiki/Hole_punching_(networking)
We employed this at a company I worked for to create a kind of BitTorrent that could circumvent firewalls for streaming video between two peers.
Note that sometimes it is NOT possible to establish a connection without the intermediary.
What you are looking for is ICE protocol. RFC 5245. This protocol is used for connecting two peers through NAT traversal. There are some open source libraries and also some proprietary libraries for this. You can search google with ICE implementation.
You will also need to read about some additional protocols. These are used with ICE protocol. They are STUN and TURN.
For some cases you can't make P2P call 100% time. You will have to use a relay server. Like if the NAT combination of two peers are Symmetric vs Symmetric/PRC. That relay server is called TURN server.
Some technique like Port forwarding and TCP/UDP hole punching will help you to increase P2P rates.
See this answer for more information about which combination of NAT will require a relay server and which don't.
Thank you. I will be looking further into ICE, STUN, TURN, and hole-punching.
I also found n2n which looks like almost exactly what I wanted.
https://github.com/meyerd/n2n
http://xmodulo.com/configure-peer-to-peer-vpn-linux.html
With n2n, one makes a VPN with a super node that all other edge nodes know.
But once the introductions are made, the super node can be absent.
This was exactly what I wanted. I hope it works across platforms (linux, MacOS, Windows).
Again, I am still researching before implementation, so your advice was very important to me.
Thank you.
Use PJNATH. Its open source.
http://www.pjsip.org/pjnath/docs/html/
There is not much open source on NAT Traversal. As far as I know PJNATH is good.
For server you can use Google's Open source STUN and TURN server.

using XMPP or WebSocket, why there is a server needed in real-time communication between users?

At the bottom, it's all about socket communications. If there is some way to get the ip of the both users, why can't the connection be directly setup between the users instead of having to go thru a server in the middle?
My 2 cents:
No one out there forces us to have a server based real-time communication model. Infact XMPP have an extension called "Serverless Messaging" which defines how to communicate over local or wide-area networks using the principles of zero-configuration networking for endpoint discovery and the syntax of XML streams and XMPP messaging for real-time communication. This method uses DNS-based Service Discovery and Multicast DNS to discover entities that support the protocol, including their IP addresses and preferred ports.
P2P chat applications have been for over a decade now. Having a server in the middle is purely a decision dependent upon your application needs. If your application can live with chats getting lost while the user was transitioning between online/offline status, then you can very well have a direct P2P model going. Similarly, there are a loads and loads of advantages (contact list management, avatars, entity discovery, presence authorization, offline messages, ....) when it comes to choosing a server based messaging model. If you try to have all this right inside your P2P based clients, they might die or under-perform because of all the work they will need to perform by themselves.
"WebSockets" were not designed for P2P/Serverless communication, rather they were designed to provide a standardized PUSH semantic over stateless HTTP protocol. In short, "WebSockets" is a standardized way replacing hacky comet, long-polling, chunked-encoding, jsonp, iframe-based and various other technique developers have been using to simulate server push over HTTP.
Named WebSockets (if someday it is fully and widely supported) could be the solution.
http://namedwebsockets.github.io/spec/
Named WebSockets are useful in a variety of collaborative local device
and local network scenarios: Discover matching peer services on the
local device and/or the local network.
Direct communication between users is possible in Peer To Peer (P2P) networks. In P2P each participant can act as client as well as server. But for P2P networks you need to write a separate program to make the communication possible.
Web Sockets let you leverage existing common browsers as clients. All depends on what is the purpose of your application and how you want to deploy it.
If there is some way to get the ip of the both users
You nailed the answer right in your question.
Most machines I use have IP address of 192.168.0.10 (or similar from 192.168. private network) and are deep, deep behind several layers of NAT. With the end of free IPv4 address pool and IPv6 nowhere near sight, this is the reality most users live. Having a stable intermediary of known, routable address helps a ton working around this issue.
WebSockets don't allow the socket to listen for connections, only to connect as a client to a server (not reverse). Technically they could make it allow this, but as far as I understand the spec doesn't currently (nor is it expected to) allow listen functionality for WebSockets.
The new WebRTC (http://www.webrtc.org/) spec looks like it might support peer-to-peer connections. I have not played with WebRTC at all so I'm not in a position to comment on it. I think it would be a bit more involved than WebSocket stuff. Maybe someone who knows WebRTC better can chime in. (Also apart from the latest version of Chrome I'm not sure if any of the other browsers really support WebRTC yet).

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

Peer-to-peer chat with the iPhone

I am aware of how many times this has been asked based on searching StackOverflow, but I am still hoping someone could tell me whether I am wrong...
I am creating a peer-to-peer chat app for the iPhone. My initial idea was to avoid using a server, so Bonjour came to mind. I was happy coding for quite a while and implemented a lot of fancy features, but two days ago I started testing with two clients from different subnets and found that the clients couldn't connect to each other! I suddenly realized that Bonjour is meant for local networks and that a DNS server is necessary for wide area service broadcasting. Do I really need a server for Internet peer-to-peer chat? Are there any other options that do not involve using a server on the iOS platform?
I am wondering how you can do a chat app without using a server. There are many cheap solutions out there, Amazon has its own service, Google does as well. You can try first without even having to pay a cent.
I found the following from apple developer guide. This should answer your question -
Does Bonjour work between multiple subnets?
Yes. The first release of DNS Service Discovery (DNS-SD) for Mac OS X concentrated on Multicast DNS (mDNS) for single-link networks because this was the environment worst served by IP software. Starting in Mac OS X 10.4, Bonjour now uses Dynamic DNS Update (RFC 2316) and unicast DNS queries to enable wide-area service discovery.
To answer the question, the only way is for you to carry a list of all possible participants, and their current IP address, and for each possible participant to report to all others each time their IP Address changes. So, if you have 100 possible participants, then you must tell 99 others when your IP Address changes, and those 99 must tell you when their IP Address changes.
Bonjour may work on a LAN, a WAN or even a WAN, but it will never work on the internet.
The role of the server is so that each end point only need to tell one end point (the server) when it changes. My advice is get a cheap internet host, with a basic PHP / MySQL capabilities, and write yourself a very simple script to post and get user identities.

Can socket connections be multiplexed?

Is it possible to multiplex sa ocket connection?
I need to establish multiple connections to yahoo messenger and i am looking for a way to do this efficiently without having to hold a socket open for each client connection.
so far i have to use one socket for each client and this does not scale well above 50,000 connections.
oh, my solution is for a TELCO, so i need to at least hit 250,000 to 500,000 connections
i'm planing to bind multiple IP addresses to a single NIC to beat the 65k port restriction per IP address.
Please i would any help, insight i can get.
**most of my other questions on this site have gone un-answered :) **
Thanks
This is an interesting question about scaling in a serious situation.
You are essentially asking, "How do I establish N connections to an internet service, where N is >= 250,000".
The only way to do this effectively and efficiently is to cluster. You cannot do this on a single host, so you will need to be able to fragment and partition your client base into a number of different servers, so that each is only handling a subset.
The idea would be for a single server to hold open as few connections as possible (spreading out the connectivity evenly) while holding enough connections to make whatever service you're hosting viable by keeping inter-server communication to a minimum level. This will mean that any two connections that are related (such as two accounts that talk to each other a lot) will have to be on the same host.
You will need servers and network infrastructure that can handle this. You will need a subnet of ip addresses, each server will have to have stateless communication with the internet (i.e. your router will not be doing any NAT in order to not have to track 250,000+ connections).
You will have to talk to AOL. There is no way that AOL will be able to handle this level of connectivity without considering cutting your connection off. Any service of this scale would have to be negotiated with AOL so both you and they would be able to handle the connectivity.
There are i/o multiplexing technologies that you should investigate. Kqueue and epoll come to mind.
In order to write this massively concurrent and teleco grade solution, I would recommend investigating erlang. Erlang is designed for situations such as these (multi-server, massively-multi-client, massively-multithreaded telecommunications grade software). It is currently used for running Ericsson telephone exchanges.
While you can listen on a socket for multiple incoming connection requests, when the connection is established, it connects a unique port on the server to a unique port on the client. In order to multiplex a connection, you need to control both ends of the pipe and have a protocol that allows you to switch contexts from one virtual connection to another or use a stateless protocol that doesn't care about the client's identity. In the former case you'd need to implement it in the application layer so that you could reuse existing connections. In the latter case you could get by using a proxy that keeps track of which server response goes to which client. Since you're connecting to Yahoo Messenger, I don't think you'll be able to do this since it requires an authenticated connection and it assumes that each connection corresponds to a single user.
You can only multiplex multiple connections over a single socket if the other end supports such an operation.
In other words it's a function protocol - sockets don't have any native support for it.
I doubt yahoo messenger protocol has any support for it.
An alternative (to multiple IPs on a single NIC) is to design your own multiplexing protocol and have satellite servers that convert from the multiplex protocol to the yahoo protocol.
I'll trow in another approach you could consider (depending on how desperate you are).
Note that operating system TCP/IP implementations need to be general purpose, but you are only interested in a very specific use-case. So it might make sense to implement a cut-down version of TCP/IP (which only handles your use-case, but does that very well) in your application code.
For example, if you are using Linux, you could route a couple of IP addresses to a tun interface and have your application handle the IP packets for that tun interface. That way you can implement TCP/IP (optimised for your use-case) entirely in your application and avoid any operating system restriction on the number of open connections.
Of course, it's quite a bit of work doing the TCP/IP yourself, but it really depends on how desperate you are - i.e. how much hardware can you afford to throw at the problem.
500,000 arbitrary yahoo messenger connections - is your telco doing this on behalf of Yahoo? It seems like whatever solution has been in place for many years now should be scalable with the help of Moore's Law - and as far as I know all the IM clients have been pretty effective for a long time, and there's no pressing increase in demand that I can think of.
Why isn't this a reasonable problem to address with hardware plus traditional solutions?