Changeset 1030 for pjproject/trunk
- Timestamp:
- Mar 1, 2007 11:39:08 PM (18 years ago)
- Location:
- pjproject/trunk/pjlib-util
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjlib-util/include/pjlib-util/errno.h
r1002 r1030 302 302 /** 303 303 * @hideinitializer 304 * Invalid STUN MESSAGE-INTEGRITY attribute position in message. 305 * STUN MESSAGE-INTEGRITY must be put last in the message, or before 306 * FINGERPRINT attribute. 307 */ 308 #define PJLIB_UTIL_ESTUNMSGINT (PJLIB_UTIL_ERRNO_START+117)/* 320117 */ 304 * Found non-FINGERPRINT attribute after MESSAGE-INTEGRITY. This is not 305 * valid since MESSAGE-INTEGRITY MUST be the last attribute or the 306 * attribute right before FINGERPRINT before the message. 307 */ 308 #define PJLIB_UTIL_ESTUNMSGINTPOS (PJLIB_UTIL_ERRNO_START+118)/* 320118 */ 309 /** 310 * @hideinitializer 311 * Found attribute after FINGERPRINT. This is not valid since FINGERPRINT 312 * MUST be the last attribute in the message. 313 */ 314 #define PJLIB_UTIL_ESTUNFINGERPOS (PJLIB_UTIL_ERRNO_START+119)/* 320119 */ 309 315 /** 310 316 * @hideinitializer … … 313 319 * present), the USERNAME attribute must be present in the message. 314 320 */ 315 #define PJLIB_UTIL_ESTUNNOUSERNAME (PJLIB_UTIL_ERRNO_START+1 18)/* 320118*/321 #define PJLIB_UTIL_ESTUNNOUSERNAME (PJLIB_UTIL_ERRNO_START+120)/* 320120 */ 316 322 317 323 -
pjproject/trunk/pjlib-util/src/pjlib-util/stun_msg.c
r1021 r1030 989 989 990 990 /* Check that struct size is valid */ 991 pj_assert(sizeof(pj_stun_msg_integrity_attr)== STUN_MSG_INTEGRITY_LEN);991 pj_assert(sizeof(pj_stun_msg_integrity_attr)==ATTR_LEN); 992 992 993 993 /* Create attribute */ … … 1857 1857 for (i=0; i<msg->attr_count; ++i) { 1858 1858 const struct attr_desc *adesc; 1859 const pj_stun_attr_hdr *attr_hdr; 1860 1861 attr_hdr = msg->attr[i]; 1859 const pj_stun_attr_hdr *attr_hdr = msg->attr[i]; 1862 1860 1863 1861 if (attr_hdr->type == PJ_STUN_ATTR_MESSAGE_INTEGRITY) { … … 1890 1888 buf += printed; 1891 1889 buf_size -= printed; 1890 } 1891 1892 /* We may have stopped printing attribute because we found 1893 * MESSAGE-INTEGRITY or FINGERPRINT. Scan the rest of the 1894 * attributes. 1895 */ 1896 for ( ++i; i<msg->attr_count; ++i) { 1897 const pj_stun_attr_hdr *attr_hdr = msg->attr[i]; 1898 1899 /* There mustn't any attribute after FINGERPRINT */ 1900 PJ_ASSERT_RETURN(afingerprint == NULL, PJLIB_UTIL_ESTUNFINGERPOS); 1901 1902 if (attr_hdr->type == PJ_STUN_ATTR_MESSAGE_INTEGRITY) { 1903 /* There mustn't be MESSAGE-INTEGRITY before */ 1904 PJ_ASSERT_RETURN(amsg_integrity == NULL, 1905 PJLIB_UTIL_ESTUNMSGINTPOS); 1906 amsg_integrity = (pj_stun_msg_integrity_attr*) attr_hdr; 1907 1908 } else if (attr_hdr->type == PJ_STUN_ATTR_FINGERPRINT) { 1909 afingerprint = (pj_stun_fingerprint_attr*) attr_hdr; 1910 } 1892 1911 } 1893 1912 … … 1922 1941 /* Should not happen for message generated by us */ 1923 1942 pj_assert(PJ_FALSE); 1924 return PJLIB_UTIL_ESTUNMSGINT ;1943 return PJLIB_UTIL_ESTUNMSGINTPOS; 1925 1944 1926 1945 } else if (i == msg->attr_count-2) { … … 1928 1947 /* Should not happen for message generated by us */ 1929 1948 pj_assert(PJ_FALSE); 1930 return PJLIB_UTIL_ESTUNMSGINT ;1949 return PJLIB_UTIL_ESTUNMSGINTPOS; 1931 1950 } else { 1932 1951 afingerprint = (pj_stun_fingerprint_attr*) msg->attr[i+1]; -
pjproject/trunk/pjlib-util/src/pjlib-util/stun_session.c
r1021 r1030 572 572 /* Encode message */ 573 573 status = pj_stun_msg_encode(tdata->msg, tdata->pkt, tdata->max_len, 574 0, NULL, &tdata->pkt_size);574 0, password, &tdata->pkt_size); 575 575 if (status != PJ_SUCCESS) { 576 576 pj_stun_msg_destroy_tdata(sess, tdata); -
pjproject/trunk/pjlib-util/src/pjstun-client/client_main.c
r1008 r1030 20 20 #include <pjlib.h> 21 21 22 #include <conio.h>23 24 22 25 23 #define THIS_FILE "client_main.c" 24 25 static struct global 26 { 27 pj_stun_endpoint *endpt; 28 pj_pool_t *pool; 29 pj_caching_pool cp; 30 pj_timer_heap_t *th; 31 pj_stun_session *sess; 32 unsigned sess_options; 33 pj_sock_t sock; 34 pj_thread_t *thread; 35 pj_bool_t quit; 36 37 pj_sockaddr_in dst_addr; /**< destination addr */ 38 39 } g; 40 41 static struct options 42 { 43 char *dst_addr; 44 char *dst_port; 45 char *realm; 46 char *user_name; 47 char *password; 48 pj_bool_t use_fingerprint; 49 } o; 26 50 27 51 … … 34 58 } 35 59 36 static pj_status_t on_send_msg(pj_stun_ tx_data *tdata,60 static pj_status_t on_send_msg(pj_stun_session *sess, 37 61 const void *pkt, 38 62 pj_size_t pkt_size, 39 unsigned addr_len, 40 const pj_sockaddr_t *dst_addr) 41 { 42 pj_sock_t sock; 63 const pj_sockaddr_t *dst_addr, 64 unsigned addr_len) 65 { 43 66 pj_ssize_t len; 44 67 pj_status_t status; 45 68 46 sock = (pj_sock_t) pj_stun_session_get_user_data(tdata->sess);47 48 69 len = pkt_size; 49 status = pj_sock_sendto( sock, pkt, &len, 0, dst_addr, addr_len);70 status = pj_sock_sendto(g.sock, pkt, &len, 0, dst_addr, addr_len); 50 71 51 72 if (status != PJ_SUCCESS) … … 55 76 } 56 77 57 static void on_bind_response(pj_stun_session *sess, 58 pj_status_t status, 59 pj_stun_tx_data *request, 60 const pj_stun_msg *response) 61 { 62 my_perror("on_bind_response()", status); 63 } 64 65 int main() 66 { 67 pj_stun_endpoint *endpt = NULL; 68 pj_pool_t *pool = NULL; 69 pj_caching_pool cp; 70 pj_timer_heap_t *th = NULL; 71 pj_stun_session *sess; 72 pj_sock_t sock = PJ_INVALID_SOCKET; 78 static void on_request_complete(pj_stun_session *sess, 79 pj_status_t status, 80 pj_stun_tx_data *tdata, 81 const pj_stun_msg *response) 82 { 83 if (status == PJ_SUCCESS) { 84 puts("Client transaction completes"); 85 } else { 86 my_perror("Client transaction error", status); 87 } 88 } 89 90 static int worker_thread(void *unused) 91 { 92 PJ_UNUSED_ARG(unused); 93 94 while (!g.quit) { 95 pj_time_val timeout = {0, 50}; 96 pj_fd_set_t readset; 97 int n; 98 99 pj_timer_heap_poll(g.th, NULL); 100 101 PJ_FD_ZERO(&readset); 102 PJ_FD_SET(g.sock, &readset); 103 104 n = pj_sock_select(g.sock+1, &readset, NULL, NULL, &timeout); 105 if (n > 0) { 106 if (PJ_FD_ISSET(g.sock, &readset)) { 107 char buffer[512]; 108 pj_ssize_t len; 109 pj_sockaddr_in addr; 110 int addrlen; 111 pj_status_t rc; 112 113 len = sizeof(buffer); 114 addrlen = sizeof(addr); 115 rc = pj_sock_recvfrom(g.sock, buffer, &len, 0, &addr, &addrlen); 116 if (rc == PJ_SUCCESS && len > 0) { 117 rc = pj_stun_session_on_rx_pkt(g.sess, buffer, len, 118 PJ_STUN_IS_DATAGRAM|PJ_STUN_CHECK_PACKET, 119 NULL, &addr, addrlen); 120 if (rc != PJ_SUCCESS) 121 my_perror("Error processing packet", rc); 122 } 123 } 124 } else if (n < 0) 125 pj_thread_sleep(50); 126 } 127 128 return 0; 129 } 130 131 static int init() 132 { 73 133 pj_sockaddr_in addr; 74 134 pj_stun_session_cb stun_cb; 75 pj_stun_tx_data *tdata;76 pj_str_t s;77 135 pj_status_t status; 136 137 g.sock = PJ_INVALID_SOCKET; 78 138 79 139 status = pj_init(); 80 140 status = pjlib_util_init(); 81 141 82 pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0); 83 84 pool = pj_pool_create(&cp.factory, NULL, 1000, 1000, NULL); 85 86 status = pj_timer_heap_create(pool, 1000, &th); 87 pj_assert(status == PJ_SUCCESS); 88 89 status = pj_stun_endpoint_create(&cp.factory, 0, NULL, th, &endpt); 90 pj_assert(status == PJ_SUCCESS); 91 92 status = pj_sock_socket(PJ_AF_INET, PJ_SOCK_DGRAM, 0, &sock); 93 pj_assert(status == PJ_SUCCESS); 94 95 status = pj_sockaddr_in_init(&addr, pj_cstr(&s, "127.0.0.1"), PJ_STUN_PORT); 142 pj_caching_pool_init(&g.cp, &pj_pool_factory_default_policy, 0); 143 144 if (o.dst_addr) { 145 pj_str_t s; 146 pj_uint16_t port; 147 148 if (o.dst_port) 149 port = (pj_uint16_t) atoi(o.dst_port); 150 else 151 port = PJ_STUN_PORT; 152 153 status = pj_sockaddr_in_init(&g.dst_addr, pj_cstr(&s, o.dst_addr), port); 154 if (status != PJ_SUCCESS) { 155 my_perror("Invalid address", status); 156 return status; 157 } 158 159 printf("Destination address set to %s:%d\n", o.dst_addr, (int)port); 160 } else { 161 printf("Error: address must be specified\n"); 162 return PJ_EINVAL; 163 } 164 165 g.pool = pj_pool_create(&g.cp.factory, NULL, 1000, 1000, NULL); 166 167 status = pj_timer_heap_create(g.pool, 1000, &g.th); 168 pj_assert(status == PJ_SUCCESS); 169 170 status = pj_stun_endpoint_create(&g.cp.factory, 0, NULL, g.th, &g.endpt); 171 pj_assert(status == PJ_SUCCESS); 172 173 status = pj_sock_socket(PJ_AF_INET, PJ_SOCK_DGRAM, 0, &g.sock); 174 pj_assert(status == PJ_SUCCESS); 175 176 status = pj_sockaddr_in_init(&addr, NULL, 0); 96 177 pj_assert(status == PJ_SUCCESS); 97 178 98 179 pj_memset(&stun_cb, 0, sizeof(stun_cb)); 99 180 stun_cb.on_send_msg = &on_send_msg; 100 stun_cb.on_bind_response = &on_bind_response; 101 102 status = pj_stun_session_create(endpt, NULL, &stun_cb, &sess); 103 pj_assert(status == PJ_SUCCESS); 104 105 pj_stun_session_set_user_data(sess, (void*)sock); 106 107 status = pj_stun_session_create_bind_req(sess, &tdata); 108 pj_assert(status == PJ_SUCCESS); 109 110 status = pj_stun_session_send_msg(sess, 0, sizeof(addr), &addr, tdata); 111 pj_assert(status == PJ_SUCCESS); 112 113 while (1) { 114 pj_fd_set_t rset; 115 int n; 116 pj_time_val timeout; 117 118 if (kbhit()) { 119 if (_getch()==27) 120 break; 181 stun_cb.on_request_complete = &on_request_complete; 182 183 status = pj_stun_session_create(g.endpt, NULL, &stun_cb, &g.sess); 184 pj_assert(status == PJ_SUCCESS); 185 186 if (o.realm) { 187 pj_str_t r, u, p; 188 189 if (o.user_name == NULL) { 190 printf("error: username must be specified\n"); 191 return PJ_EINVAL; 121 192 } 122 123 PJ_FD_ZERO(&rset); 124 PJ_FD_SET(sock, &rset); 125 126 timeout.sec = 0; timeout.msec = 100; 127 128 n = pj_sock_select(FD_SETSIZE, &rset, NULL, NULL, &timeout); 129 130 if (PJ_FD_ISSET(sock, &rset)) { 131 char pkt[512]; 132 pj_ssize_t len; 133 134 len = sizeof(pkt); 135 status = pj_sock_recv(sock, pkt, &len, 0); 136 if (status == PJ_SUCCESS) { 137 pj_stun_session_on_rx_pkt(sess, pkt, len, NULL); 193 if (o.password == NULL) 194 o.password = ""; 195 g.sess_options = PJ_STUN_USE_LONG_TERM_CRED; 196 pj_stun_session_set_long_term_credential(g.sess, pj_cstr(&r, o.realm), 197 pj_cstr(&u, o.user_name), 198 pj_cstr(&p, o.password)); 199 puts("Using long term credential"); 200 } else if (o.user_name) { 201 pj_str_t u, p; 202 203 if (o.password == NULL) 204 o.password = ""; 205 g.sess_options = PJ_STUN_USE_SHORT_TERM_CRED; 206 pj_stun_session_set_short_term_credential(g.sess, 207 pj_cstr(&u, o.user_name), 208 pj_cstr(&p, o.password)); 209 puts("Using short term credential"); 210 } else { 211 puts("Credential not set"); 212 } 213 214 if (o.use_fingerprint) 215 g.sess_options |= PJ_STUN_USE_FINGERPRINT; 216 217 status = pj_thread_create(g.pool, "stun", &worker_thread, NULL, 218 0, 0, &g.thread); 219 if (status != PJ_SUCCESS) 220 return status; 221 222 return PJ_SUCCESS; 223 } 224 225 226 static int shutdown() 227 { 228 if (g.thread) { 229 g.quit = 1; 230 pj_thread_join(g.thread); 231 pj_thread_destroy(g.thread); 232 g.thread = NULL; 233 } 234 if (g.sess) 235 pj_stun_session_destroy(g.sess); 236 if (g.endpt) 237 pj_stun_endpoint_destroy(g.endpt); 238 if (g.sock != PJ_INVALID_SOCKET) 239 pj_sock_close(g.sock); 240 if (g.th) 241 pj_timer_heap_destroy(g.th); 242 if (g.pool) 243 pj_pool_release(g.pool); 244 245 pj_pool_factory_dump(&g.cp.factory, PJ_TRUE); 246 pj_caching_pool_destroy(&g.cp); 247 248 return PJ_SUCCESS; 249 } 250 251 static void menu(void) 252 { 253 puts("Menu:"); 254 puts(" b Send Bind request"); 255 puts(" q Quit"); 256 puts(""); 257 printf("Choice: "); 258 } 259 260 static void console_main(void) 261 { 262 while (!g.quit) { 263 char input[10]; 264 265 menu(); 266 267 fgets(input, sizeof(input), stdin); 268 269 switch (input[0]) { 270 case 'b': 271 { 272 pj_stun_tx_data *tdata; 273 pj_status_t rc; 274 275 rc = pj_stun_session_create_bind_req(g.sess, &tdata); 276 pj_assert(rc == PJ_SUCCESS); 277 278 rc = pj_stun_session_send_msg(g.sess, g.sess_options, 279 &g.dst_addr, sizeof(g.dst_addr), 280 tdata); 281 if (rc != PJ_SUCCESS) 282 my_perror("Error sending STUN request", rc); 138 283 } 284 break; 285 case 'q': 286 g.quit = 1; 287 break; 288 default: 289 break; 139 290 } 140 141 pj_timer_heap_poll(th, NULL); 142 } 291 } 292 } 293 294 295 static void usage(void) 296 { 297 puts("Usage: pjstun_client TARGET [OPTIONS]"); 298 puts(""); 299 puts("where TARGET is \"host[:port]\""); 300 puts(""); 301 puts("and OPTIONS:"); 302 puts(" --realm, -r Set realm of the credential"); 303 puts(" --username, -u Set username of the credential"); 304 puts(" --password, -p Set password of the credential"); 305 puts(" --fingerprint, -F Use fingerprint for outgoing requests"); 306 puts(" --help, -h"); 307 } 308 309 int main(int argc, char *argv[]) 310 { 311 struct pj_getopt_option long_options[] = { 312 { "realm", 1, 0, 'r'}, 313 { "username", 1, 0, 'u'}, 314 { "password", 1, 0, 'p'}, 315 { "fingerprint",0, 0, 'F'}, 316 { "help", 0, 0, 'h'} 317 }; 318 int c, opt_id; 319 char *pos; 320 pj_status_t status; 321 322 while((c=pj_getopt_long(argc,argv, "r:u:p:hF", long_options, &opt_id))!=-1) { 323 switch (c) { 324 case 'r': 325 o.realm = pj_optarg; 326 break; 327 case 'u': 328 o.user_name = pj_optarg; 329 break; 330 case 'p': 331 o.password = pj_optarg; 332 break; 333 case 'h': 334 usage(); 335 return 0; 336 case 'F': 337 o.use_fingerprint = PJ_TRUE; 338 break; 339 default: 340 printf("Argument \"%s\" is not valid. Use -h to see help", 341 argv[pj_optind]); 342 return 1; 343 } 344 } 345 346 if (pj_optind == argc) { 347 puts("Error: TARGET is needed"); 348 return 1; 349 } 350 351 if ((pos=pj_ansi_strchr(argv[pj_optind], ':')) != NULL) { 352 o.dst_addr = argv[pj_optind]; 353 *pos = '\0'; 354 o.dst_port = pos+1; 355 } else { 356 o.dst_addr = argv[pj_optind]; 357 } 358 359 status = init(); 360 if (status != PJ_SUCCESS) 361 goto on_return; 362 363 console_main(); 143 364 144 365 on_return: 145 if (sock != PJ_INVALID_SOCKET) 146 pj_sock_close(sock); 147 if (endpt) 148 pj_stun_endpoint_destroy(endpt); 149 if (th) 150 pj_timer_heap_destroy(th); 151 if (pool) 152 pj_pool_release(pool); 153 pj_caching_pool_destroy(&cp); 154 155 return 0; 156 } 157 158 366 shutdown(); 367 return status ? 1 : 0; 368 } 369 -
pjproject/trunk/pjlib-util/src/pjstun-srv-test/server_main.c
r1021 r1030 124 124 struct service *svc = (struct service *) pj_stun_session_get_user_data(sess); 125 125 pj_stun_tx_data *tdata; 126 pj_stun_auth_policy pol;127 126 pj_status_t status; 128 127 … … 131 130 if (status != PJ_SUCCESS) 132 131 return status; 133 134 #if 1135 pj_memset(&pol, 0, sizeof(pol));136 pol.type = PJ_STUN_POLICY_STATIC_LONG_TERM;137 pol.user_data = NULL;138 pol.data.static_long_term.realm = pj_str("realm");139 pol.data.static_long_term.username = pj_str("user");140 pol.data.static_long_term.password = pj_str("password");141 pol.data.static_long_term.nonce = pj_str("nonce");142 status = pj_stun_verify_credential(pkt, pkt_len, msg, &pol, tdata->pool,143 &tdata->msg);144 if (!tdata->msg)145 return status;146 #endif147 132 148 133 /* Create MAPPED-ADDRESS attribute */ … … 388 373 #else 389 374 pj_status_t status; 390 char line[10];391 375 392 376 status = pj_thread_create(server.pool, "stun_server", &worker_thread, NULL, … … 395 379 return server_perror(THIS_FILE, "create_thread() error", status); 396 380 397 puts("Press ENTER to quit"); 398 fgets(line, sizeof(line), stdin); 381 while (!server.thread_quit_flag) { 382 char line[10]; 383 384 printf("Menu:\n" 385 " q Quit\n" 386 "Choice:"); 387 388 fgets(line, sizeof(line), stdin); 389 if (line[0] == 'q') 390 server.thread_quit_flag = 1; 391 } 399 392 400 393 #endif
Note: See TracChangeset
for help on using the changeset viewer.