[PYTHON] I tried using coturn

I tried using turnserver, which I wanted to use but didn't use, so make a note of it.

environment

Sakura Cloud CentOS release 6.5 (Final) Server coturn

build coturn

In my environment, I prepared the source in *** / user / local / src / ***. When I first did *** configure ***, I was told that *** libevent2 *** was also required, so I got it from here.

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

First with *** libevent2 ***

./configure
make
make install

*** coturn *** as well

./configure
make
make install

If you build without specifying anything,

> which turnserver
/usr/local/bin/turnserver

An executable file is created in *** / usr / local / bin ***. The *** conf *** file is created in *** / usr / local / etc ***. You can create a template, copy it and modify it.

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

Basically the default, but the edited item is

#Global IP
listening-ip=XXX.XXX.XXX.XXX
#localhost specification
relay-ip=127.0.0.1
min-port=49152
max-port=65535
verbose #I want to see the details of the log, so cancel it
no-tls
no-dtls
stun-only

For the time being, specify only this

Operation verification

# 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        *:*                                     

The server is running on stun (3478) with tcp and udp.

This time it's just an operation check, so I brought the client from here, but stun The header was a little different, so I rewrote it.

# default configuration 
host = argv[1]  #"Global IP"  
port = 3478
local_ip = 'My local 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)

Check the operation with this

#client
$>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:#Omitted
????ɀ"Coturn-4.3.1.2 'Tolomei'?r??΀+
from:  ('XXX.XXX.XXX.XXX', 3478)

>>header: 
0x101 64 2112a442 #Omitted
>>attrs:
32 XXX.XXX.XXX.XXX : 7878  (XOR= #Omitted) #This should be the global IP after NAT

>>> Success! XOR-MAPPED-ADDRESS= XXX.XXX.XXX.XXX:7878
END!
$>
#server
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

The server has timed out because it did not receive a second request. However, I was able to confirm to the client that the IP was (probably) returned from the server after going through NAT. I don't know much about it yet, so I haven't done anything elaborate. I wonder if it worked for the time being. Depending on the environment, nothing may be returned from the server. It worked for the time being, so I made a note of it.

Recommended Posts

I tried using coturn
I tried using parameterized
I tried using argparse
I tried using mimesis
I tried using aiomysql
I tried using Summpy
I tried using Pipenv
I tried using matplotlib
I tried using "Anvil".
I tried using Hubot
I tried using ESPCN
I tried using openpyxl
I tried using Ipython
I tried using PyCaret
I tried using cron
I tried using ngrok
I tried using face_recognition
I tried using Jupyter
I tried using PyCaret
I tried using Heapq
I tried using doctest
I tried using folium
I tried using jinja2
I tried using folium
I tried using time-window
[I tried using Pythonista 3] Introduction
I tried using easydict (memo).
I tried face recognition using Face ++
I tried using Random Forest
I tried using BigQuery ML
I tried using Amazon Glacier
I tried using git inspector
[Python] I tried using OpenPose
I tried using magenta / TensorFlow
I tried using AWS Chalice
I tried using Slack emojinator
I tried using Rotrics Dex Arm
I tried using GrabCut of OpenCV
I tried using Thonny (Python / IDE)
I tried server-client communication using tmux
I tried reinforcement learning using PyBrain
I tried deep learning using Theano
Somehow I tried using jupyter notebook
[Kaggle] I tried undersampling using imbalanced-learn
I tried shooting Kamehameha using OpenPose
I tried using the checkio API
[Python] I tried using YOLO v3
I tried asynchronous processing using asyncio
I tried scraping
I tried PyQ
I tried AutoKeras
I tried papermill
I tried django-slack
I tried Django
I tried spleeter
I tried cgo
I tried using Amazon SQS with django-celery
I tried using Azure Speech to Text.
I tried using Twitter api and Line api
I tried playing a ○ ✕ game using TensorFlow
I tried using YOUTUBE Data API V3