Osmux: Support dynamic allocation of osmux sockets
Right now, we have 1 unique Osmux socket per MGW instance.
Osmux streams (one direction) are identified by tuple: <srcIPaddr, srcPort, dstIPaddr, dstPort, dstCID>
Since we currently only have 1 socket, dstIPaddr and dstPort are constant, so we identify received messages by: <srcIPaddr, srcPort, dstCID>.
if the other peer is behind a NAT, srcIPaddr and srcPort are not really reliable easily, so we can only rely on dstCID to identify streams, and thus we share the CID range against all BSCs or connections.
We actually do something similar for RTP, let's think about it:
tuple identified by: <srcIPaddr, srcPort, dstIPaddr, dstPort, dstCID>, but in this case dstPort changes per-conn, so we actually identify streams per dstPort in this case.
So in Osmux streams, we identify based on dstCID, and in RTP, in dstPort. The problem is that dstCID is actually in range 0..255, which means we can get out of CIDs (not like with ports, were range is a lot higher).
In order to improve this situation (only 255 concurrent call legs in MGW using Osmux), here's my proposal:
VTY specifies an osmux IP (IPmsc) and a port range (PORTmsc1..100), or a port to start counting from, and dynamically allocates/binds and closes ports based on demand. These ports are allocated in MGW based on received MGCP <remoteIP,remotePort> tuple. This way we end up having 256 CIDs per <remoteIP,remotePort> tuple, aka per BSC, and which is the same, per <localPort>. Each BSC can actually open new osmux sockets themselves once the first one is full, meaning each BSC can handle also unlimited CIDs, and MSC will be fine because upon receival of this new <remoteIP,remotePort> tuple, a new osmux socket will be created.
All that also plays well with the fact that we want to group Osmux CIDs under same <remotIP,remotePort>, since the trunk frames need to be sent to that same address.So summary, in MGW:
- Add a table to match <remoteIP,remotePort> <-> <localPort>, with extra information like: publicRemoteIP, publicRemotePort, Osmux handler.
- Upon CRCX/MDCX update table: If an entry <remoteIP,remotePort> doesn't exist, create osmux socket + handler on next empty localPort, and fill the table.
- Upon receival of Osmux pkt, take <dstPort>, and use it in the table to lookup based on localPort, then we know the private and public <remoteIPaddr,port>, and we know to which Osmux handler we need to send the message.
- When we need to send on an osmux handler, we know localIp, localPort and publicRemoteIP and publicRemotePort, so we can send osmux frames correctly.
Drawbacks: We need at least 1 Osmux port per BSC.
Wins: We can handle unlimited Osmux call legs per BSC and per MSC (as long as ports are free, each port provides 256 streams). It allows us to support multiple MGWs when using Osmux, since now it's not possible afaict.