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