LoginSignup
13
11

More than 5 years have passed since last update.

coturn使ってみた

Posted at

使ってみたいと思いつつも使っていなかったturnserverを使ってみたのでメモします。

環境

さくらクラウド CentOS release 6.5 (Final)
サーバー coturn

coturnのビルド

自分の環境では/user/local/src/にソースを用意しました。
最初にconfigureした際にlibevent2も必要と言われたのでここから取得

> pwd;ls -F
/usr/local/src
libevent-2.0.21-stable/  turnserver-4.3.1.2/

まずlibevent2

./configure
make
make install

coturnも同様に

./configure
make
make install

何も指定せずにビルドすると、

> which turnserver
/usr/local/bin/turnserver

/usr/local/binに実行ファイルが作成される。
confファイルは/usr/local/etcに作成されます。
テンプレートができますので、それをコピーして修正

> pwd;ls 
/usr/local/etc
turnserver.conf  turnserver.conf.default

基本はデフォルトですが、編集した項目が

#グローバルIP
listening-ip=XXX.XXX.XXX.XXX
#localhost指定
relay-ip=127.0.0.1
min-port=49152
max-port=65535
verbose #ログの詳細がみたいので解除
no-tls
no-dtls
stun-only

とりあえずこれだけを指定

動作検証

# turnserver
0: log file opened: /var/log/turn_3786_2014-12-09.log
0: 
RFC 3489/5389/5766/5780/6062/6156 STUN/TURN Server
Version Coturn-4.3.1.2 'Tolomei'
0: 
Max number of open files/sockets allowed for this process: 4096
0: 
Due to the open files/sockets limitation,
max supported number of TURN Sessions possible is: 2000 (approximately)
0: 

==== Show him the instruments, Practical Frost: ====

0: TLS supported
0: DTLS supported
0: AEAD supported
0: SQLite is not supported
0: Redis is not supported
0: PostgreSQL is not supported
0: MySQL supported
0: MongoDB is not supported
0: OpenSSL compile-time version 0x1000105f: fresh enough
0: Default Net Engine version: 3 (UDP thread per CPU core)

=====================================================

0: Config file found: /usr/local/etc/turnserver.conf
0: Listener address to use: XXX.XXX.XXX.XXX
0: Relay address to use: 127.0.0.1
0: Config file found: /usr/local/etc/turnserver.conf
0: Domain name: 
0: Default realm: 
0: pid file created: /var/run/turnserver.pid
0: IO method (main listener thread): epoll (with changelist)
0: WARNING: I cannot support STUN CHANGE_REQUEST functionality because only one IP address is provided
0: Wait for relay ports initialization...
0:   relay 127.0.0.1 initialization...
0:   relay 127.0.0.1 initialization done
0: Relay ports initialization done
0: IO method (general relay thread): epoll (with changelist)
0: turn server id=0 created
0: IPv4. TCP listener opened on : XXX.XXX.XXX.XXX:3478
0: IPv4. UDP listener opened on: XXX.XXX.XXX.XXX:3478
0: Total UDP servers: 0
0: Total General servers: 1
0: IO method (cli thread): epoll (with changelist)
0: IPv4. CLI listener opened on : 127.0.0.1:5766
0: IO method (auth thread): epoll (with changelist)
> netstat -a
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address               Foreign Address             State      
tcp        0      0 XXX.XXX.XXX.XXX:stun        *:*                         LISTEN      
udp        0      0 XXX.XXX.XXX.XXX:stun        *:*                                     

stun(3478)にtcp,udpでサーバーが起動しています。

今回はただの動作確認なので、クライアントをここから持ってきたんですが、stunヘッダーが少し違っていたので書き換え。

# default configuration 
host = argv[1]  #"グローバルIP"  
port = 3478
local_ip = '自分のローカルIP(192.X.X.X?)'
local_port = 7878
## first bind 
def stun_binding_first(sock):
    print '\nSTUN binding request ...'
    # header
    header = struct.pack('!H',STUN_method['STUN_METHOD_BINDING']) # binding req
    header += struct.pack('!H',0x00)               # length
    header += struct.pack('!l',STUN_MAGIC_COOKIE)    # magic cookie
    header += struct.pack('!12s',genTranID())        # trans ID
    # body 
    body = struct.pack('!H',0x8022)           # software   
    body += struct.pack('!h',0x0014)          # length
    body += struct.pack('!20s','PY STUN CLIENT 0.1')#value
    # msg
    send_data = header #+ body # TODO 


    print 'Send data ...'
    r = sock.sendto(send_data,(host,port))
    print 'size=',r

    print 'Recv data ...'
    buf,address = sock.recvfrom(1024)
    print 'size=',len(buf)

    print 'data: ',buf
    print 'from: ',address

    (header,attr) = recv_resp(buf)

    # TODD: parse: realm, nonce 
    print ''
    return (header,attr)

これで動作確認

#クライアント
$>python stuncli.py XXX.XXX.XXX.XXX
STUN(RFC5389) client demo by Chris <nodexy@gmail>

Connect to server  :  XXX.XXX.XXX.XXX 3478
Bind local ip:port :  192.xxx.xxx.xxx 7878

STUN binding request ...
Send data ...
size= 20
Recv data ...
size= 84
data:#省略しました
????ɀ"Coturn-4.3.1.2 'Tolomei'?r??΀+
from:  ('XXX.XXX.XXX.XXX', 3478)

>>header: 
0x101 64 2112a442 #省略しました
>>attrs:
32 XXX.XXX.XXX.XXX : 7878  (XOR= #省略しました ) #ここがNAT以降のグローバルIPのはず

>>> Success! XOR-MAPPED-ADDRESS= XXX.XXX.XXX.XXX:7878
END!
$>
#サーバー
0: Total UDP servers: 0
0: Total General servers: 1
0: IO method (cli thread): epoll (with changelist)
0: IPv4. CLI listener opened on : 127.0.0.1:5766
0: IO method (auth thread): epoll (with changelist)
730: handle_udp_packet: New UDP endpoint: local addr XXX.XXX.XXX.XXX:3478, remote addr XXX.XXX.XXX.XXX:7878
1
730: session 000000000000000001: realm <> user <>: incoming packet BINDING processed, success
733: session 000000000000000001: closed (2nd stage), user <> realm <> origin <>, local XXX.XXX.XXX.XXX:3478, remote XXX.XXX.XXX.XXX:7878, reason: allocation watchdog determined stale session state

サーバーは2回目のリクエストがこないのでタイムアウトしています。
ただ、クライアントには(多分)NATを通った後のIPがサーバーから返却されていることが確認できました。
まだ、あまりよくわかっていませんので凝ったことは何もできていません。
とりあえず動いたかな程度ですね。
環境によってはサーバーから何も返却されないこともあるかもしれません。
とりあえず動いたのでメモしました。

13
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
11