離れたところからGrowlで通知 - UDPのパケットをSSHでポートフォワードする方法
- Growlは、リモートから通知リクエストを受ける機能がある。
- UDPの9887番ポートを使用
- が、Growlが動いているマシンと通知リクエストを行うマシンは、それぞれ異なるLANに属していて、直接通信できない。
- stoneにはUDPとTCPとを相互変換する機能があるらしい。
- 仙石浩明の日記: stone に UDP ⇔ TCP 相互変換機能を実装
- 少なくともstone-2.3dではこの機能が実装されている。(stoneのサイトからダウンロード可能)
というわけで、
な構成にすればOK
が、Mac (Mac OS X 10.4.10, Intel) だと stone (2.3d) のUDP/TCP変換がうまく動かない —もうちょっと具体的にいうと、sendtoがエラーリターンする(調査中…)—
TCP5>UDP6: sendto failed err=56: to 127.0.0.1:9889/udp
- http://developer.apple.com/documentation/Darwin/Reference/ManPages/man2/sendto.2.html
- http://developer.apple.com/documentation/Darwin/Reference/ManPages/man2/intro.2.html
56 EISCONN Socket is already connected. A connect request was made on an already connected socket; or, a sendto or sendmsg request on a connected socket specified a destination when already connected.
http://developer.apple.com/documentation/Darwin/Reference/ManPages/man2/intro.2.html
ので、Growlなマシンと同じLAN内にあるLinuxマシンでTCP→UDPの変換をしました。
図にするとこんな感じ。
┏━━━━━━━━━━━━━━━━━ ┃┌[notifier]─────────── ┃│Net::Growl ┃│↓ ┃│localhost:9887/udp ┃│ stone // stone -nr localhost:9888 localhost:9887/udp ┃│↓ ┃│localhost:9888/tcp ┃│ ssh // ssh -L 9888:localhost:9888 relay ┃└──────────────── ┗━━━━━━━━━━━━━━━━━ ↓ 〜〜〜 ↓ ┏━━━━━━━━━━━━━━━━━ ┃┌[relay ]──────────── ┃│localhost:9888/tcp ┃│ stone // stone -nr growl:9887/udp localhost:9888 ┃└──────────────── ┃ ↓ ┃┌[growl ]──────────── ┃│*:9887/udp ┃│ Growl ┃└──────────────── ┗━━━━━━━━━━━━━━━━━
追記 2007-10-22 14:05
Mac (Mac OS X 10.4.10, Intel)とFreeBSD 6.2で、
- stone-2.3d
- 本文と同じく、EISCONNが発生。
- stone.c 2.3.2.2
- 正常に通信成功。
を確認しました。対応ありがとうございました!> id:gcd san
また、『UNIXネットワークプログラミング〈Vol.1〉ネットワークAPI:ソケットとXTI』の「8.11 UDPにおけるconnect関数」(p.216) に関連する記述がありました。
要約すると、接続済みUDPソケット(connectしたもの)に対して終点指定ありのsendtoを行った場合の結果は以下のようになるそうです。
環境 | 結果 |
---|---|
4.4BSD | EISCONN |
Posix.1g | EISCONN |
Solaris 2.5 | OK |
Linux 2.6 | OK (これは私の実験の結果から) |