// register_files(tracker_task, myalias) // Registers this peer with the tracker, using 'myalias' as this peer's // alias. Also register all files in the current directory, allowing // other peers to upload those files from us. static void register_files(task_t *tracker_task, const char *myalias) { DIR *dir; struct dirent *ent; struct stat s; char buf[PATH_MAX]; size_t messagepos; assert(tracker_task->type == TASK_TRACKER); // Register address with the tracker. osp2p_writef(tracker_task->peer_fd, "ADDR %s %I:%d\n", myalias, listen_addr, listen_port); messagepos = read_tracker_response(tracker_task); message("* Tracker's response to our IP address registration:\n%s", &tracker_task->buf[messagepos]); if (tracker_task->buf[messagepos] != '2') { message("* The tracker reported an error, so I will not register files with it.\n"); return; } // Register files with the tracker. message("* Registering our files with tracker\n"); if ((dir = opendir(".")) == NULL) die("open directory: %s", strerror(errno)); while ((ent = readdir(dir)) != NULL) { int namelen = strlen(ent->d_name); // don't depend on unreliable parts of the dirent structure // and only report regular files. Do not change these lines. if (stat(ent->d_name, &s) < 0 || !S_ISREG(s.st_mode) || (namelen > 2 && ent->d_name[namelen - 2] == '.' && (ent->d_name[namelen - 1] == 'c' || ent->d_name[namelen - 1] == 'h')) || (namelen > 1 && ent->d_name[namelen - 1] == '~')) continue; char text_digest[MD5_TEXT_DIGEST_SIZE + 1]; md5_generate(ent->d_name, text_digest); osp2p_writef(tracker_task->peer_fd, "HAVE %s %s\n", ent->d_name, text_digest); messagepos = read_tracker_response(tracker_task); if (tracker_task->buf[messagepos] != '2') error("* Tracker error message while registering '%s':\n%s", ent->d_name, &tracker_task->buf[messagepos]); } closedir(dir); }
END_TEST START_TEST(test_message_parse) { struct turn_message message; struct turn_msg_hdr* hdr = NULL; struct turn_attr_hdr* attr = NULL; struct sockaddr_in daddr; struct sockaddr_in daddr2; struct iovec iov[50]; char buf[1500]; int nb = 0; size_t index = 0; uint8_t id[12]; uint16_t tab[16]; size_t tab_size = 16; unsigned char md_buf[16]; nb = turn_generate_transaction_id(id); fail_unless(nb == 0, "Failed to generate transaction ID."); daddr.sin_family = AF_INET; daddr.sin_addr.s_addr = inet_addr("127.0.0.1"); daddr.sin_port = htons(3478); memset(daddr.sin_zero, 0x00, sizeof(daddr.sin_zero)); daddr2.sin_family = AF_INET; daddr2.sin_addr.s_addr = inet_addr("192.168.0.1"); daddr2.sin_port = htons(444); memset(daddr2.sin_zero, 0x00, sizeof(daddr2.sin_zero)); /* Allocate request */ hdr = turn_msg_allocate_request_create(0, id, &iov[index]); fail_unless(hdr != NULL, "header creation failed"); index++; /* MAPPED-ADDRESS */ attr = turn_attr_mapped_address_create((struct sockaddr*)&daddr2, &iov[index]); fail_unless(attr != NULL, "attribute header creation failed"); hdr->turn_msg_len += iov[index].iov_len; index++; /* XOR-MAPPED-ADDRESS */ attr = turn_attr_xor_mapped_address_create((struct sockaddr*)&daddr2, STUN_MAGIC_COOKIE, id, &iov[index]); fail_unless(attr != NULL, "attribute header creation failed"); hdr->turn_msg_len += iov[index].iov_len; index++; /* XOR-PEER-ADDRESS */ attr = turn_attr_xor_peer_address_create((struct sockaddr*)&daddr2, STUN_MAGIC_COOKIE, id, &iov[index]); fail_unless(attr != NULL, "attribute header creation failed"); hdr->turn_msg_len += iov[index].iov_len; index++; /* XOR-RELAYED-ADDRESS */ attr = turn_attr_xor_relayed_address_create((struct sockaddr*)&daddr2, STUN_MAGIC_COOKIE, id, &iov[index]); fail_unless(attr != NULL, "attribute header creation failed"); hdr->turn_msg_len += iov[index].iov_len; index++; /* ALTERNATE-SERVER */ attr = turn_attr_alternate_server_create((struct sockaddr*)&daddr2, &iov[index]); fail_unless(attr != NULL, "attribute header creation failed"); hdr->turn_msg_len += iov[index].iov_len; index++; /* NONCE */ attr = turn_attr_nonce_create("\"heynonce\"", strlen("\"heynonce\""), &iov[index]); fail_unless(attr != NULL, "attribute header creation failed"); hdr->turn_msg_len += iov[index].iov_len; index++; /* REALM */ attr = turn_attr_realm_create("heyrealm", strlen("heyrealm"), &iov[index]); fail_unless(attr != NULL, "attribute header creation failed"); hdr->turn_msg_len += iov[index].iov_len; index++; /* USERNAME */ attr = turn_attr_username_create("ping6", strlen("ping6"), &iov[index]); fail_unless(attr != NULL, "attribute header creation failed"); hdr->turn_msg_len += iov[index].iov_len; index++; /* ERROR-CODE */ attr = turn_attr_error_create(420, "Bad request", strlen("Bad request"), &iov[index]); fail_unless(attr != NULL, "attribute header creation failed"); hdr->turn_msg_len += iov[index].iov_len; index++; /* UNKNOWN-ATTRIBUTE */ { uint16_t tab[3] = {0x0002, 0x0001, 0x0003}; uint16_t tab2[4] = {0x0001, 0x0002, 0x0003, 0x0004}; attr = turn_attr_unknown_attributes_create(tab, sizeof(tab) / sizeof(uint16_t), &iov[index]); fail_unless(attr != NULL, "attribute header creation failed"); hdr->turn_msg_len += iov[index].iov_len; index++; attr = turn_attr_unknown_attributes_create(tab2, sizeof(tab2) / sizeof(uint16_t), &iov[index]); fail_unless(attr != NULL, "attribute header creation failed"); hdr->turn_msg_len += iov[index].iov_len; index++; } /* DATA */ attr = turn_attr_data_create("data", strlen("data"), &iov[index]); fail_unless(attr != NULL, "attribute header creation failed"); hdr->turn_msg_len += iov[index].iov_len; index++; /* CHANNEL-NUMBER */ attr = turn_attr_channel_number_create(0xBEEF, &iov[index]); fail_unless(attr != NULL, "attribute header creation failed"); hdr->turn_msg_len += iov[index].iov_len; index++; /* LIFETIME */ attr = turn_attr_lifetime_create(0xDEADBEEF, &iov[index]); fail_unless(attr != NULL, "attribute header creation failed"); hdr->turn_msg_len += iov[index].iov_len; index++; /* SOFTWARE */ attr = turn_attr_software_create("Client TURN 0.1 test", strlen("Client TURN 0.1 test"), &iov[index]); fail_unless(attr != NULL, "attribute header creation failed"); hdr->turn_msg_len += iov[index].iov_len; index++; /* REQUESTED-TRANSPORT */ attr = turn_attr_requested_transport_create(IPPROTO_UDP, &iov[index]); fail_unless(attr != NULL, "attribute header creation failed"); hdr->turn_msg_len += iov[index].iov_len; index++; /* EVEN-PORT */ attr = turn_attr_even_port_create(0x80, &iov[index]); fail_unless(attr != NULL, "attribute header creation failed"); hdr->turn_msg_len += iov[index].iov_len; index++; /* RESERVATION-TOKEN */ { uint8_t token[8] = {1, 2, 3, 4, 5, 6, 7, 8}; attr = turn_attr_reservation_token_create(token, &iov[index]); fail_unless(attr != NULL, "attribute header creation failed"); hdr->turn_msg_len += iov[index].iov_len; index++; } /* DONT-FRAGMENT */ attr = turn_attr_dont_fragment_create(&iov[index]); fail_unless(attr != NULL, "attribute header create failed"); hdr->turn_msg_len += iov[index].iov_len; index++; /* FINGERPRINT */ attr = turn_attr_fingerprint_create(0xDEADBEEF, &iov[index]); fail_unless(attr != NULL, "attribute header creation failed"); hdr->turn_msg_len += iov[index].iov_len; index++; /* MESSAGE-INTEGRITY */ attr = turn_attr_message_integrity_create(NULL, &iov[index]); fail_unless(attr != NULL, "attribute header creation failed"); hdr->turn_msg_len += iov[index].iov_len; index++; /* convert to big endian */ hdr->turn_msg_len = htons(hdr->turn_msg_len); /* after convert STUN/TURN message length to big endian we can calculate * HMAC-SHA1 */ /* index -1 because we do not take into account MESSAGE-INTEGRITY attribute */ md5_generate(md_buf, "login:domain.org:password", strlen("login:domain.org:password")); turn_calculate_integrity_hmac_iov(iov, index - 1, md_buf, sizeof(md_buf), ((struct turn_attr_message_integrity*)attr)->turn_attr_hmac); /* put iovec into a raw buffer */ { char* ptr = buf; for(nb = 0 ; nb < index ; nb++) { memcpy(ptr, iov[nb].iov_base, iov[nb].iov_len); ptr += iov[nb].iov_len; } } nb = turn_parse_message(buf, sizeof(buf), &message, tab, &tab_size); /* test if the header and all the attributes are present */ fail_unless(message.msg != NULL, "header must be present"); fail_unless(message.mapped_addr != NULL, "mapped_addr must be present"); fail_unless(message.peer_addr != NULL, "peer_addr must be present"); fail_unless(message.relayed_addr != NULL, "relayed_addr must be present"); fail_unless(message.alternate_server != NULL, "alternate_server must be present"); fail_unless(message.xor_mapped_addr != NULL, "xor_mapped_addr must be present"); fail_unless(message.reservation_token != NULL, "reservation_token must be present"); fail_unless(message.data != NULL, "data must be present"); fail_unless(message.channel_number != NULL, "channel_number must be present"); fail_unless(message.lifetime != NULL, "lifetime must be present"); fail_unless(message.nonce != NULL, "nonce must be present"); fail_unless(message.realm != NULL, "realm must be present"); fail_unless(message.username != NULL, "username must be present"); fail_unless(message.even_port != NULL, "even_port must be present"); fail_unless(message.requested_transport != NULL, "requested_transport must be present"); fail_unless(message.dont_fragment != NULL, "dont_fragment must be present"); fail_unless(message.unknown_attribute != NULL, "unknown_attribute must be present"); fail_unless(message.message_integrity == NULL, "fingerprint MUST be the last attribute"); fail_unless(message.fingerprint != NULL, "fingerprint must be present"); fail_unless(message.software != NULL, "software must be present"); fail_unless(message.error_code != NULL, "error_code must be present"); iovec_free_data(iov, index); }