written on Thursday, September 13, 2012
Есть такой хороший SIP-клиент Telephone.app. В ней используется одна хорошая библиотека pjsip, правда она под GPL, а библиотеки под GPL публикуют не очень хорошие люди.
И есть у этой библиотеки достаточно стремное поведение, которое наверняка где-то сто раз описано, но лишний раз тыкнуть палочкой будет не лишним.
В заметке про webrtc есть описание примитивной реализации voip, краткое содержание тако: две программы говорят друг-другу UDP адреса, через котрые будут обмениваться голосовым трафиком. Лирические отступления по повоу кодеков и, аутентификации, виртуального номеронабирателя и виртуального подъема трубки оставим за кадром.
Современный интернет - это такая жопа с дефицитом адресов и криво настроенными маршрутизаторами, в которой у каждой хреновины есть по сто разных адресов.
Один из частных случаев - связь двух абонентов внутри одной локальной сети.
Первый абонент имеет внутренний адрес 192.168.1.44, второй абонент - 192.168.1.45, внешний адрес роутера, через который они ходят наружу - 109.109.255.230, а сервер, на котором они зарегистрированы имеет какой-то свой адрес, например 109.200.152.80
Когда один абонент звонит другому, поскольку они общаются SIP-пакетами через сервер, они оба указывают в качестве своего адреса, внешний адрес роутера:
192.168.1.44 -> 109.200.152.80 -> 192.168.1.45 c=IN IP4 109.109.255.230 m=audio 5320 RTP/AVP 102 192.168.1.45 -> 109.200.152.80 -> 192.168.1.44 c=IN IP4 109.109.255.230 m=audio 4001 RTP/AVP 102
Поскольку роутер может быть настроен черезжопу или кто-то из абонентов окажется дохуя умным и отправит свой внутренний адрес, может произойти следующее: первый абонент будет отправлять свой поток на внешний адрес роутера, а получать входящий с внутреннего адреса второго абонента:
// at 192.168.1.44 sendto(192.168.1.45, msg) // at 192.168.1.45 sendto(109.109.255.230:4001, msg) recvmsg(&addr, &msg) // addr == 192.168.1.44:4001
Я пока не увидел в стандартах какого-то указания по этому поводу, но pjmedia делают финт ушами - если голосовой поток приходит не с того адреса, который указан в SDP, то на адрес в SDP все забивают и дальнейшая коммуникация идет уже туда.
То есть живой MiTM, позволяющий угнать голосовую сессию и сесть посередие, зная адреса обоих абонентов и послав им парочку валидных RTP пакетов, даже с дурным пейлоадом или шумом.
Я понимаю, зачем это сделано - вдруг у абонента кривой роутер, кривой UA или вообще сменился адрес во время разговора. Я также понимаю, что в том софте, который я видел, шифрования голосового потока нет или оно выключено при сборке, либо при конфигурации. А если нет шифрования, то все изначально плохо, а активный MiTM просто делает все еще хуже, при том, что шифрование сразу все исправило бы.