coturn 简介

一. 安装

1.1. 下载

  • git
git clone https://github.com/coturn/coturn.git
  • 压缩包安装
wget https://github.com/coturn/coturn/archive/4.5.0.8.tar.gz

1.2. 安装

cd coturn
./configure
make 
sudo make install

注: 如果编译出错,记得安装相关依赖。

二. 配置

我这里在 /etc 下单独建立了个 turnserver 的目录,将 coturn 配置文件 turnserver.conf 拷贝过来。

sudo mkdir /etc/turnserver
sudo cp coturn/examples/etc/turnserver.conf /etc/turnserver/
sudo cp coturn/examples/etc/turn_server_*.pem /etc/turnserver/

配置 /etc/turnserver/turnserver.conf

# TURN 的监听端口,默认 3478
listening-port=3478

# 监听 relay server 的地址
listening-ip=192.168.110.146

# 可以和 listening IP 一样
relay-ip=192.168.110.146

# 同上
external-ip=192.168.110.146

# 输出详细过程
verbose

# TURN 消息中可使用 FINGERPRINT
fingerprint

# 开启长期证书机制
lt-cred-mech

# 设置静态账户
user=test:test

# 
realm=mytest

# 关闭 TLS 和 DTLS 监听
no-tls
no-dtls

# 连接的生命周期,默认 10min
stale-nonce=600

# 证书和私钥文件
cert=/etc/turnserver/turn_server_cert.pem
pkey=/etc/turnserver/turn_server_pkey.pem

# 屏蔽 loopback, multicast IP 地址
no-loopback-peers
no-multicast-peers

# 支持移动 ICE
mobility
no-cli

三. 启动 & 测试

3.1. Server

turnserver -v -L 192.168.110.146 -a -f -r mytest -c /etc/turnserver/turnserver.conf
  • -L 指定 relay 的监听 IP
  • -a 使用 long-term credential
  • -f fingerprints
  • -r 指定 realm
  • -c 指定配置文件

3.2. Client

turnutils_uclient -u test -w test -v -y 192.168.110.146
  • -u 指定用户名
  • -w 指定密码
  • -v 详细输出
  • -y 使用 client-to-client 连接

看到如下提示则为成功:

0: success: 0x4690
0: Total connect time is 0
1: start_mclient: msz=4, tot_send_msgs=0, tot_recv_msgs=0, tot_send_bytes ~ 0, tot_recv_bytes ~ 0
2: start_mclient: msz=4, tot_send_msgs=0, tot_recv_msgs=0, tot_send_bytes ~ 0, tot_recv_bytes ~ 0
3: start_mclient: msz=4, tot_send_msgs=1, tot_recv_msgs=1, tot_send_bytes ~ 100, tot_recv_bytes ~ 100
4: start_mclient: msz=4, tot_send_msgs=10, tot_recv_msgs=10, tot_send_bytes ~ 1000, tot_recv_bytes ~ 1000
5: start_mclient: msz=4, tot_send_msgs=15, tot_recv_msgs=15, tot_send_bytes ~ 1500, tot_recv_bytes ~ 1500
5: done, connection 0x1fcd600 closed.
5: done, connection 0x7f40c0d10010 closed.
5: done, connection 0x7f40c0b9a010 closed.
5: done, connection 0x7f40c0bbb010 closed.
5: start_mclient: tot_send_msgs=20, tot_recv_msgs=20
5: start_mclient: tot_send_bytes ~ 2000, tot_recv_bytes ~ 2000
5: Total transmit time is 5
5: Total lost packets 0 (0.000000%), total send dropped 0 (0.000000%)
5: Average round trip delay 0.000000 ms; min = 0 ms, max = 0 ms
5: Average jitter 0.650000 ms; min = 0 ms, max = 2 ms

四. 代码流程

注: 基于 coturn-4.5.0.8 版本

4.1. 大体框架涉及的函数

...各种初始化
read_config_file() // 读取配置文件
setup_server() // 设置
  -> setup_listener()
    -> turnipports_create()        // 设置 turn 端口范围
    -> turn_event_base_new()       // event
  -> allocate_relay_addrs_ports()  // relay 地址
  -> setup_listener()
  -> setup_general_relay_servers() // 设置 relay
  -> setup_auth_server()           // 认证相关

4.2. 设置 relay 相关

setup_general_relay_servers()
  -> setup_relay_server()
    -> relay_receive_message()
      -> handle_relay_message()    // 读取 event 发往 relay 的消息
        -> open_client_connection_session()
          -> client_input_handler()
            -> read_client_connection()
              -> handle_turn_command()     // 处理 TURN 协议的各种请求或数据发送与接收
              -> write_client_connection() // 返回数据给 Client
  • 设置 event 的回调函数 relay_receive_message()
  • relay_receive_message() 循环从 event buffer 中读取数据交给 handle_relay_message()

4.3. 处理请求或数据

handle_turn_command(server, ss, in_buffer, nbh, &resp_constructed, can_resume);
handle_turn_command()
  -> stun_is_request_str()     // 判断 method 是否是请求
    -> handle_turn_allocate()          // 处理 Allocate Request
    -> handle_turn_create_permission() // 处理 CreatePermission Request
    -> handle_turn_refresh()           // 处理 Refresh Request
    -> handle_turn_channel_bind()      // 处理 ChannelBind Request
  -> stun_is_indication_str() // 判断 method 是否是数据
    -> handle_turn_send()              // 处理 Send Request
  • nbh 是从 server 的 ioa_engine_handle 结构的 bufs 中创建并传入进来的
  • 处理结束后,将 resp_constructed 的值赋为 1。
struct _ioa_engine
{
  super_memory_t *sm;
  struct event_base *event_base;
  int deallocate_eb;
  int verbose;
  turnipports* tp;
  rtcp_map *map_rtcp;
  stun_buffer_list bufs;
  // ...
}
typedef struct _stun_buffer_list {
	stun_buffer_list_elem *head;
	size_t tsz;
} stun_buffer_list;

4.4. 分析请求并构造返回数据

handle_turn_allocate() 举例来说:

handle_turn_allocate(server, ss, &tid, resp_constructed,
    &err_code, &reason, unknown_attrs, &ua_num, in_buffer, nbh);
handle_turn_allocate()
  -> stun_attr_get_first_str()        // 获取第一个属性
  -> stun_attr_get_type()             // 依次获取其他属性
  -> stun_attr_get_len()              // 获取属性长度
  -> stun_attr_get_value()            // 获取属性 value
  -> stun_set_allocate_response_str() // 创建返回数据
    -> stun_attr_add_addr_str()       // 添加各种属性
  • 读取 in_buffer 中的 nbh 结构
  • 将 nbh 强转为 stun_buffer_list_elem 结构,其中 next 是链表的指针,buf 承载属性等信息,根据 len 和 offset 来获取属性信息
  • 填充 nbh 结构,用于返回数据
typedef struct _stun_buffer_list_elem {
	struct _stun_buffer_list_elem *next;
	stun_buffer buf;
} stun_buffer_list_elem;
typedef struct _stun_buffer {
  u08bits	channel[STUN_CHANNEL_HEADER_LENGTH];
  u08bits	buf[STUN_BUFFER_SIZE];
  size_t	len;
  u16bits	offset;
  u08bits	coffset;
} stun_buffer;

4.5. 真正的返回数据

write_client_connection(server, ss, nbh, TTL_IGNORE, TOS_IGNORE);
write_client_connection()
  -> send_data_from_ioa_socket_nbh()
    -> udp_send()
      -> sendto()
  • 参数中的 nbh 就是前面构造出来的
  • udp_send() 使用的 fd 是参数 server 的 client_socket 字段中的 fd
<think>嗯,用户想了解coturn客户端的配置和使用,我需要先回忆一下coturn的基本信息。首先,coturn是一个开源的TURN/STUN服务器,用于NAT穿透,这在WebRTC应用中非常重要。客户端配置的话,可能需要设置服务器地址、端口、凭证等。 我应该先介绍coturn的作用,比如它如何帮助在P2P连接中穿越NAT。然后,可能需要分步骤讲解客户端的配置,比如在WebRTC中如何配置ICE服务器,使用用户名和密码。还要注意不同的客户端可能有不同的配置方式,比如JavaScript、移动端等。 用户可能需要示例代码,比如在JavaScript中如何配置RTCPeerConnection使用coturn服务器。同时,要提醒用户注意安全性,比如使用TLS和临时凭证。另外,生成相关问题的时候,应该考虑用户可能的后续疑问,比如如何生成凭证、如何测试配置是否正确、常见错误排查等。 还要确保使用正确的LaTeX格式,虽然这个问题可能涉及的技术术语不太需要数学公式,但如果有参数或命令示例,可能需要用代码块展示。另外,引用部分需要加上标识,比如coturn的官网或其他资源。需要检查是否有遗漏的配置项,比如端口号是否默认3478,是否需要开启TURN REST API等。最后,确保回答结构清晰,分点说明,让用户能逐步理解和操作。</think>### coturn客户端使用与配置 coturn是一个开源的TURN/STUN服务器,用于实现NAT穿透,尤其在WebRTC实时通信中至关重要[^1]。客户端需通过ICE协议与coturn交互,以下是关键配置步骤: #### 1. 基础配置参数 - **服务器地址与协议** 客户端需指定coturn服务器的域名/IP及端口,例如: ```javascript const peerConnection = new RTCPeerConnection({ iceServers: [{ urls: "turn:coturn.example.com:3478", // TURN服务地址 username: "临时凭证", credential: "动态生成的密码" }] }); ``` 若启用TLS加密则使用`turns:`协议头,默认端口5349。 #### 2. 认证机制 - **长期凭证** 在`turnserver.conf`中配置静态用户: ``` user=test:123456 ``` 对应客户端直接使用该用户名密码。 - **临时凭证(推荐)** 通过TURN REST API动态生成短期凭证[^2]: ```python import hashlib, time timestamp = int(time.time()) + 3600 # 有效期1小时 username = f"{timestamp}:userid" password = hashlib.sha1(f"{secret_key}:{username}".encode()).hexdigest() ``` #### 3. 网络穿透测试 使用`turnutils_uclient`工具验证服务: ```bash turnutils_uclient -v -u 用户名 -w 密码 coturn.example.com ``` 成功连接会显示类似`0: channel opened`的日志。 #### 4. 安全配置 - 强制TLS加密传输 - 设置合理的凭证有效期(建议5-30分钟) - 限制客户端IP范围(通过`allowed-peer-ip`配置)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值