rob@76: OSCgroups client and server rob@76: (c) Ross Bencina 2005-2013 rob@76: rob@76: rob@76: OSCgroups is a system for routing OSC messages between a group of rob@76: collaborating users. It is designed to make joining and leaving a rob@76: group simple, and to overcome the problem of connecting multiple rob@76: users behind different NAT routers using a NAT traversal server with rob@76: the usual "NAT hole punching" scheme (you can put that into google rob@76: for more info). OSCgroups also implements basic group functionality rob@76: similar to the concept of channels in internet relay chat. rob@76: rob@76: To use OSCgroups, a group of collaborators (or processes) each pick a rob@76: unique user name and password, and all agree on a shared group name rob@76: and group password. They then each run an OSCgroups enabled client rob@76: which connects with a server to retrieve the names, ip addresses and rob@76: port numbers of all other group members. This information can easily rob@76: be refreshed over time allowing dynamic group membership, this also rob@76: supports situations where ip addresses may change. Once an rob@76: OSCgroups client has the list of user names, addresses and port rob@76: numbers it could do a number of things, for example it could rob@76: implement message forwarding to named endpoints (i.e. always send rob@76: these messages to user 'fred' no matter what his address is) or to rob@76: multicast messages to all other members of the group. rob@76: rob@76: In this initial release of OSCgroups there is only one client: rob@76: OscGroupClient -- which implements multicast to other group members. rob@76: Future versions may include more advanced point-to-point routing rob@76: functionality. rob@76: rob@76: This distribution contains OSCGroupServer and OSCGroupClient, both rob@76: written in C++. It is envisiaged that OSCgroups clients could also be rob@76: implemented in other environments such as SuperCollider or max.msp. rob@76: rob@76: rob@76: rob@76: COMPILING rob@76: --------- rob@76: rob@76: OSCgroups is implemented using oscpack, a simple C++ library for rob@76: packing and unpacking OSC messages. In general you should try rob@76: to build OSCgroups with a similarly timestamped snapshot of rob@76: oscpack. rob@76: rob@76: To compile oscgroups, unzip the oscgroups and oscpack archives rob@76: (or check out from the svn repository) to obtain the following rob@76: directory structure: rob@76: rob@76: rob@76: /oscgroups rob@76: Makefile rob@76: ... (other files from the oscgroups zip) rob@76: /bin rob@76: rob@76: /oscpack rob@76: /osc rob@76: /ip rob@76: .... rob@76: rob@76: rob@76: On Unix just type rob@76: rob@76: >make rob@76: rob@76: in the oscgroups directory and the OscGroupServer and OscGroupClient rob@76: should end up in the bin directory. If you encounter any compilation rob@76: errors please email me. For other platforms take a look at the rob@76: makefile and work out which source files you need to build and which rob@76: include directories need to be on your include path. rob@76: rob@76: There is a batch file for building with MinGW on Windows (make.MinGW32.bat) rob@76: rob@76: There is a CMakeLists.txt file that you can use with CMake. rob@76: rob@76: OSCgroups should compile everywhere oscpack compiles, which is at rob@76: least Windows, Linux and MacOSX. rob@76: rob@76: rob@76: rob@76: RUNNING rob@76: ------- rob@76: rob@76: * OSCGroupsServer rob@76: rob@76: rob@76: To run your own OSCGroupsServer simply run the OSCGroupsServer, rob@76: use -h to get a list of possible parameters. You can specify rob@76: the port the server listens on, limit the number of connected rob@76: users and groups, set a timeout after which the server will rob@76: forget inactive users, and specify a file to which log messages rob@76: will be written. Without any parameters the server will run rob@76: on the default port 22242 rob@76: rob@76: rob@76: * OscGroupClient rob@76: rob@76: This client registers with the server and establishes contact with rob@76: all the other members of the specified group. It then listens on a rob@76: specified port and transfers all traffic from there to other group rob@76: members. It also forwards all traffic from other group members to rob@76: another specified port on the local machine. The arguments are as rob@76: follows (you can get a summary of this info by just passing -h). Note rob@76: that all arguments must be supplied, and given in the order listed rob@76: below. rob@76: rob@76: servername rob@76: an internet name such as oscgroups.iua.upf.edu or an ip address rob@76: such as 193.145.55.19 rob@76: rob@76: serverport rob@76: the udp port which the server is listening on, the server rob@76: defaults to 22242 rob@76: rob@76: localtoremoteport rob@76: the local port used to connect with the server and to other rob@76: group members. rob@76: rob@76: localtxport rob@76: this is the port which OscGroupClient listens to and forwards rob@76: to other group members. direct your OSC traffic to this port. rob@76: rob@76: localrxport rob@76: this is the port which OscGroupClient forwards trafic from rob@76: other users to. you should configure your OSC application to listen rob@76: to this port. rob@76: rob@76: username rob@76: a unique user name used to identify you with other clients. rob@76: rob@76: password rob@76: a password which is used to try to make sure that no one else rob@76: pretends to be you on the server. this isn't secure but it helps. rob@76: rob@76: groupname rob@76: a name that all group members agree on, like a user name it rob@76: should be unique. rob@76: rob@76: grouppassword rob@76: a password for the group. users without the correct password rob@76: won't be admitted to the group. rob@76: rob@76: rob@76: All of the port numbers specified need to be different. If multiple rob@76: users are behind the same NAT and you experience difficulties. you rob@76: might like to try all using a different value for localtoremoteport rob@76: for each user, although this shouldn't usually be necessary. rob@76: rob@76: OSCGroups will report if you failed to register with the server rob@76: because of an incorrect password. This could be caused by another user rob@76: with the same name being connected to the server. So try to pick rob@76: your usernames to be unique, or use your own server. Like IRC, the rob@76: server forgets names quickly if no client is using them. rob@76: rob@76: rob@76: Here's an example: rob@76: rob@76: rob@76: ./OscGroupClient oscgroups.iua.upf.edu 22242 22243 22244 22245 tim rob@76: timspassword testgroup testpass rob@76: rob@76: rob@76: with the above running in one window you could run oscdump: rob@76: rob@76: OscDump localhost 22245 rob@76: rob@76: then all messages sent by all other group members (but not you) would rob@76: be dumped to the console. rob@76: rob@76: If you're lucky there is an OSCGroupsServer running on oscgroups.iua.upf.edu rob@76: port 22242 rob@76: rob@76: rob@76: If you want to run OscGroupClient on the same machine as the server rob@76: make sure that you use a real ip address or machine name (not rob@76: localhost or 127.0.0.1) as the servername parameter of OscGroupClient rob@76: otherwise it won't work properly. This is a kind of bug which I don't rob@76: really want to fix right now. rob@76: rob@76: rob@76: If you have a software firewall installed on your machine you may need rob@76: to ensure that the OscGroupClient executable is registered with the rob@76: firewall. If you update the executable you may need to re-register it. rob@76: Also remember that the local-to-remote port (22242) must not be blocked rob@76: by your firewall. rob@76: rob@76: rob@76: rob@76: PLANNED EXTENSIONS rob@76: ------------------ rob@76: rob@76: The planned extensions can be summarised as: rob@76: rob@76: - serverless operation for locally connected machines using IP broadcast rob@76: rob@76: - compute and display ping times rob@76: rob@76: - point-to-point routing in OscGroupClient rob@76: rob@76: rob@76: rob@76: NOTES rob@76: ----- rob@76: rob@76: This is an initial version and it's possible that a few things will rob@76: change, including the protocol. Right now it isn't foolproof, the rob@76: references below suggest it probably works behind about 80-85% of rob@76: routers on the market today -- this is a little worrying in the rob@76: context of using it to perform live, however the alternatives involve rob@76: providing fallback strategies such as forwarding via a server using rob@76: TCP on port 80 -- perhaps that can be added for version 2. There is a rob@76: nice analysis of the Skype protocol in the references section. There rob@76: are clearly many things which could be added to OSCGroups, but for rob@76: now the idea is to keep it simple. rob@76: rob@76: I mentioned above that OSCGroups clients could be implemented with rob@76: other OSC enabled applications. While this is true in theory, I'm not rob@76: sure how practical it would be because the NAT traversal strategy rob@76: requires that the same socket be used for sending and receiving data rob@76: to the outside world. The OscGroupClient uses a fixed port number for rob@76: this, but that isn't strictly required. rob@76: rob@76: The server protocol has been designed to be pretty general, and rob@76: OscGroupClient doesn't really take full advantage of it. For example, rob@76: it would be easy to implement point-to-point routing (send these rob@76: messages only to these users), or to fire events when users join or rob@76: leave a group. rob@76: rob@76: Right now OscGroupClient parses every OSC packet it sees: this isn't rob@76: ideal but it also isn't easy to avoid. One method might be to use rob@76: non-bundled messages for /groupclient/ping messages so that it can rob@76: only process non-bundled packets. Another option is to take advantage rob@76: of the fact that every message is parsed and allow the packets to rob@76: pass routing information. In reality the routing information would be rob@76: easier to use if it was embedded in outbound packets (eg send this rob@76: packet to this username). It's not obvious to me how to cleanly rob@76: provide an interface to this functionality (or if it is really rob@76: needed) so it hasn't been done. rob@76: rob@76: rob@76: rob@76: SOME REFERENCES rob@76: --------------- rob@76: rob@76: NAT and Peer-to-peer networking rob@76: Dan Kegel rob@76: http://alumnus.caltech.edu/~dank/peer-nat.html rob@76: rob@76: Peer-to-Peer Communication Across Network Address Translators rob@76: Bryan Ford, Pyda Srisuresh, Dan Kegel rob@76: http://www.brynosaurus.com/pub/net/p2pnat/ rob@76: rob@76: RFC3489: STUN - Simple Traversal of User Datagram Protocol (UDP) rob@76: Through Network Address Translators (NATs) rob@76: http://www.ietf.org/rfc/rfc3489.txt rob@76: rob@76: An Analysis of Skype Peer-to-Peer Internet Telephony Protocol rob@76: Salman A. Baset and Henning Schulzrinne rob@76: http://arxiv.org/ftp/cs/papers/0412/0412017.pdf rob@76: rob@76: Beej's Guide to Network Programming rob@76: http://www.ecst.csuchico.edu/~beej/guide/net/ rob@76: rob@76: rob@76: Thanks to John Lazzaro for hooking me up with the right information. rob@76: rob@76: rob@76: rob@76: