client_main.c
来自「一个开源的sip源代码」· C语言 代码 · 共 753 行 · 第 1/2 页
C
753 行
my_perror("Error sending STUN request", rc);
}
static void send_allocate_request(pj_bool_t allocate)
{
pj_stun_tx_data *tdata;
pj_status_t rc;
rc = pj_stun_session_create_req(g.sess, PJ_STUN_ALLOCATE_REQUEST,
NULL, &tdata);
pj_assert(rc == PJ_SUCCESS);
if (BANDWIDTH != -1) {
pj_stun_msg_add_uint_attr(tdata->pool, tdata->msg,
PJ_STUN_ATTR_BANDWIDTH, BANDWIDTH);
}
if (!allocate) {
pj_stun_msg_add_uint_attr(tdata->pool, tdata->msg,
PJ_STUN_ATTR_LIFETIME, 0);
} else {
if (LIFETIME != -1) {
pj_stun_msg_add_uint_attr(tdata->pool, tdata->msg,
PJ_STUN_ATTR_LIFETIME, LIFETIME);
}
if (REQ_TRANSPORT != -1) {
pj_stun_msg_add_uint_attr(tdata->pool, tdata->msg,
PJ_STUN_ATTR_REQ_TRANSPORT, REQ_TRANSPORT);
}
if (REQ_PORT_PROPS != -1) {
pj_stun_msg_add_uint_attr(tdata->pool, tdata->msg,
PJ_STUN_ATTR_REQ_PORT_PROPS, REQ_PORT_PROPS);
}
if (REQ_IP) {
pj_sockaddr_in addr;
pj_str_t tmp;
pj_sockaddr_in_init(&addr, pj_cstr(&tmp, REQ_IP), 0);
pj_stun_msg_add_sockaddr_attr(tdata->pool, tdata->msg,
PJ_STUN_ATTR_REQ_IP, PJ_FALSE,
&addr, sizeof(addr));
}
}
rc = pj_stun_session_send_msg(g.sess, PJ_FALSE,
&g.srv_addr, sizeof(g.srv_addr),
tdata);
pj_assert(rc == PJ_SUCCESS);
}
static void send_sad_request(pj_bool_t set)
{
pj_stun_tx_data *tdata;
pj_status_t rc;
if (g.peer_addr.sin_addr.s_addr == 0 ||
g.peer_addr.sin_port == 0)
{
puts("Error: peer address is not set");
return;
}
rc = pj_stun_session_create_req(g.sess,
PJ_STUN_SET_ACTIVE_DESTINATION_REQUEST,
NULL, &tdata);
pj_assert(rc == PJ_SUCCESS);
if (set) {
pj_stun_msg_add_sockaddr_attr(tdata->pool, tdata->msg,
PJ_STUN_ATTR_REMOTE_ADDR, PJ_FALSE,
&g.peer_addr, sizeof(g.peer_addr));
}
rc = pj_stun_session_send_msg(g.sess, PJ_FALSE,
&g.srv_addr, sizeof(g.srv_addr),
tdata);
pj_assert(rc == PJ_SUCCESS);
}
static void send_send_ind(void)
{
pj_stun_tx_data *tdata;
int len;
pj_status_t rc;
if (g.peer_addr.sin_addr.s_addr == 0 ||
g.peer_addr.sin_port == 0)
{
puts("Error: peer address is not set");
return;
}
len = strlen(g.data);
if (len==0) {
puts("Error: data is not set");
return;
}
rc = pj_stun_session_create_ind(g.sess, PJ_STUN_SEND_INDICATION, &tdata);
pj_assert(rc == PJ_SUCCESS);
pj_stun_msg_add_sockaddr_attr(tdata->pool, tdata->msg,
PJ_STUN_ATTR_REMOTE_ADDR, PJ_FALSE,
&g.peer_addr, sizeof(g.peer_addr));
pj_stun_msg_add_binary_attr(tdata->pool, tdata->msg,
PJ_STUN_ATTR_DATA, (pj_uint8_t*)g.data, len);
rc = pj_stun_session_send_msg(g.sess, PJ_FALSE,
&g.srv_addr, sizeof(g.srv_addr),
tdata);
pj_assert(rc == PJ_SUCCESS);
}
static void send_raw_data_to_srv(void)
{
pj_ssize_t len;
if (g.srv_addr.sin_addr.s_addr == 0 ||
g.srv_addr.sin_port == 0)
{
puts("Error: server address is not set");
return;
}
len = strlen(g.data);
if (len==0) {
puts("Error: data is not set");
return;
}
len = strlen(g.data);
pj_sock_sendto(g.sock, g.data, &len, 0, &g.srv_addr, sizeof(g.srv_addr));
}
static void send_raw_data_to_relay(void)
{
pj_ssize_t len;
if (g.relay_addr.sin_addr.s_addr == 0 ||
g.relay_addr.sin_port == 0)
{
puts("Error: relay address is not set");
return;
}
len = strlen(g.data);
if (len==0) {
puts("Error: data is not set");
return;
}
len = strlen(g.data);
pj_sock_sendto(g.peer_sock, g.data, &len, 0, &g.relay_addr, sizeof(g.relay_addr));
}
static pj_status_t parse_addr(const char *input,
pj_sockaddr_in *addr)
{
const char *pos;
pj_str_t ip;
pj_uint16_t port;
pj_sockaddr_in tmp_addr;
pos = pj_ansi_strchr(input, ':');
if (pos==NULL) {
puts("Invalid format");
return -1;
}
ip.ptr = (char*)input;
ip.slen = pos - input;
port = (pj_uint16_t)atoi(pos+1);
if (port==0) {
puts("Invalid port");
return -1;
}
if (pj_sockaddr_in_init(&tmp_addr, &ip, port)!=PJ_SUCCESS) {
puts("Invalid address");
return -1;
}
pj_memcpy(addr, &tmp_addr, sizeof(tmp_addr));
return PJ_SUCCESS;
}
static void set_peer_addr(void)
{
char addr[64];
printf("Current peer address: %s:%d\n",
pj_inet_ntoa(g.peer_addr.sin_addr),
pj_ntohs(g.peer_addr.sin_port));
printf("Input peer address in IP:PORT format: ");
fflush(stdout);
fgets(addr, sizeof(addr), stdin);
if (parse_addr(addr, &g.peer_addr) != PJ_SUCCESS) {
return;
}
}
static void menu(void)
{
puts("Menu:");
printf(" pr Set peer address (currently %s:%d)\n",
pj_inet_ntoa(g.peer_addr.sin_addr), pj_ntohs(g.peer_addr.sin_port));
printf(" dt Set data (currently \"%s\")\n", g.data);
puts(" br Send Bind request");
puts(" ar Send Allocate request");
puts(" dr Send de-Allocate request");
puts(" sr Send Set Active Destination request");
puts(" cr Send clear Active Destination request");
puts(" si Send data with Send Indication");
puts(" rw Send raw data to TURN server");
puts(" rW Send raw data to relay address");
puts(" q Quit");
puts("");
printf("Choice: ");
}
static void console_main(void)
{
while (!g.quit) {
char input[10];
menu();
fgets(input, sizeof(input), stdin);
if (0) {
} else if (input[0]=='d' && input[1]=='t') {
printf("Input data: ");
fgets(g.data, sizeof(g.data_buf), stdin);
} else if (input[0]=='p' && input[1]=='r') {
set_peer_addr();
} else if (input[0]=='b' && input[1]=='r') {
send_bind_request();
} else if (input[0]=='a' && input[1]=='r') {
send_allocate_request(PJ_TRUE);
} else if (input[0]=='d' && input[1]=='r') {
send_allocate_request(PJ_FALSE);
} else if (input[0]=='s' && input[1]=='r') {
send_sad_request(PJ_TRUE);
} else if (input[0]=='c' && input[1]=='r') {
send_sad_request(PJ_FALSE);
} else if (input[0]=='s' && input[1]=='i') {
send_send_ind();
} else if (input[0]=='r' && input[1]=='w') {
send_raw_data_to_srv();
} else if (input[0]=='r' && input[1]=='W') {
send_raw_data_to_relay();
} else if (input[0]=='q') {
g.quit = 1;
}
}
}
static void usage(void)
{
puts("Usage: pjstun_client TARGET [OPTIONS]");
puts("");
puts("where TARGET is \"host[:port]\"");
puts("");
puts("and OPTIONS:");
puts(" --realm, -r Set realm of the credential");
puts(" --username, -u Set username of the credential");
puts(" --password, -p Set password of the credential");
puts(" --nonce, -N Set NONCE");
puts(" --fingerprint, -F Use fingerprint for outgoing requests");
puts(" --peer, -P Set peer address (address is in HOST:PORT format)");
puts(" --data, -D Set data");
puts(" --help, -h");
}
int main(int argc, char *argv[])
{
struct pj_getopt_option long_options[] = {
{ "realm", 1, 0, 'r'},
{ "username", 1, 0, 'u'},
{ "password", 1, 0, 'p'},
{ "nonce", 1, 0, 'N'},
{ "fingerprint",0, 0, 'F'},
{ "peer", 1, 0, 'P'},
{ "data", 1, 0, 'D'},
{ "help", 0, 0, 'h'}
};
int c, opt_id;
char *pos;
pj_status_t status;
g.data = g.data_buf;
pj_ansi_strcpy(g.data, "Hello world");
while((c=pj_getopt_long(argc,argv, "r:u:p:N:hF", long_options, &opt_id))!=-1) {
switch (c) {
case 'r':
o.realm = pj_optarg;
break;
case 'u':
o.user_name = pj_optarg;
break;
case 'p':
o.password = pj_optarg;
break;
case 'N':
o.nonce = pj_optarg;
break;
case 'h':
usage();
return 0;
case 'F':
o.use_fingerprint = PJ_TRUE;
break;
case 'P':
o.peer_addr = pj_optarg;
break;
case 'D':
g.data = pj_optarg;
break;
default:
printf("Argument \"%s\" is not valid. Use -h to see help",
argv[pj_optind]);
return 1;
}
}
if (pj_optind == argc) {
puts("Error: TARGET is needed");
return 1;
}
if ((pos=pj_ansi_strchr(argv[pj_optind], ':')) != NULL) {
o.srv_addr = argv[pj_optind];
*pos = '\0';
o.srv_port = pos+1;
} else {
o.srv_addr = argv[pj_optind];
}
status = init();
if (status != PJ_SUCCESS)
goto on_return;
console_main();
on_return:
shutdown();
return status ? 1 : 0;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?