/* Remplis la table de sockets, et le tableau faisant la correspondance entre sockets et fichiers. */ void init_peers_connections(struct torrent_info *ti) { /* Construction du handshake, identique pour tous. */ struct proto_client_handshake* hs = construct_handshake(ti->torrent) ; int i,j ; u_int id_sock ; /* Parcours des pairs */ i=0 ; while(i < ti->peerlist->nbPeers) { if(!init_peer_connection(&ti->peerlist->pentry[i],hs)) { /* connection échouée, on supprime le pair */ for(j = i ; j < ti->peerlist->nbPeers-1 ; j++) { ti->peerlist->pentry[j] = ti->peerlist->pentry[j+1] ; } ti->peerlist->nbPeers-- ; } else { id_sock = get_name(socket_map,(u_int)ti->peerlist->pentry[i].sockfd) ; socket_to_file[id_sock] = ti->torrent->filehash ; socket_to_peer[id_sock] = ti->peerlist->pentry[i].peerId ; peers[id_sock] = &ti->peerlist->pentry[i] ; pthread_mutex_lock(&ti->peerlist->pentry[i].lock) ; ti->peerlist->pentry[i].pieces = createbitfield(ti->torrent->filelength,ti->torrent->piecelength) ; /* bitfield initialisé à 00...0 */ pthread_mutex_unlock(&ti->peerlist->pentry[i].lock) ; if(ti->torrent->have->nbpiece >0) /* pas la peine d'envoyer le bitfield si on n'a pas de pieces */ send_bitfield(&ti->peerlist->pentry[i],ti->torrent,-2) ; i++ ; } } free(hs); }
int main(int argc, char *argv[]) { struct socket *sock; struct sockaddr_in addr; socklen_t addr_len; char line[LINE_LENGTH + 1]; unsigned int unordered, policy, value, id, seconds; unsigned int i; struct channel *channel; const int on = 1; struct sctp_assoc_value av; struct sctp_event event; struct sctp_udpencaps encaps; struct sctp_initmsg initmsg; uint16_t event_types[] = {SCTP_ASSOC_CHANGE, SCTP_PEER_ADDR_CHANGE, SCTP_REMOTE_ERROR, SCTP_SHUTDOWN_EVENT, SCTP_ADAPTATION_INDICATION, SCTP_SEND_FAILED_EVENT, SCTP_STREAM_RESET_EVENT, SCTP_STREAM_CHANGE_EVENT}; if (argc > 1) { usrsctp_init(atoi(argv[1]), NULL, debug_printf); } else { usrsctp_init(9899, NULL, debug_printf); } #ifdef SCTP_DEBUG usrsctp_sysctl_set_sctp_debug_on(SCTP_DEBUG_NONE); #endif usrsctp_sysctl_set_sctp_blackhole(2); if ((sock = usrsctp_socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP, receive_cb, NULL, 0, &peer_connection)) == NULL) { perror("socket"); } init_peer_connection(&peer_connection); if (argc > 2) { memset(&encaps, 0, sizeof(struct sctp_udpencaps)); encaps.sue_address.ss_family = AF_INET6; encaps.sue_port = htons(atoi(argv[2])); if (usrsctp_setsockopt(sock, IPPROTO_SCTP, SCTP_REMOTE_UDP_ENCAPS_PORT, (const void*)&encaps, (socklen_t)sizeof(struct sctp_udpencaps)) < 0) { perror("setsockopt"); } } if (usrsctp_setsockopt(sock, IPPROTO_SCTP, SCTP_RECVRCVINFO, &on, sizeof(int)) < 0) { perror("setsockopt SCTP_RECVRCVINFO"); } if (usrsctp_setsockopt(sock, IPPROTO_SCTP, SCTP_EXPLICIT_EOR, &on, sizeof(int)) < 0) { perror("setsockopt SCTP_EXPLICIT_EOR"); } /* Allow resetting streams. */ av.assoc_id = SCTP_ALL_ASSOC; av.assoc_value = SCTP_ENABLE_RESET_STREAM_REQ | SCTP_ENABLE_CHANGE_ASSOC_REQ; if (usrsctp_setsockopt(sock, IPPROTO_SCTP, SCTP_ENABLE_STREAM_RESET, &av, sizeof(struct sctp_assoc_value)) < 0) { perror("setsockopt SCTP_ENABLE_STREAM_RESET"); } /* Enable the events of interest. */ memset(&event, 0, sizeof(event)); event.se_assoc_id = SCTP_ALL_ASSOC; event.se_on = 1; for (i = 0; i < sizeof(event_types)/sizeof(uint16_t); i++) { event.se_type = event_types[i]; if (usrsctp_setsockopt(sock, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(event)) < 0) { perror("setsockopt SCTP_EVENT"); } } memset(&initmsg, 0, sizeof(struct sctp_initmsg)); initmsg.sinit_num_ostreams = 5; initmsg.sinit_max_instreams = 65535; if (usrsctp_setsockopt(sock, IPPROTO_SCTP, SCTP_INITMSG, &initmsg, sizeof(struct sctp_initmsg)) < 0) { perror("setsockopt SCTP_INITMSG"); } if (argc == 5) { /* operating as client */ memset(&addr, 0, sizeof(struct sockaddr_in)); addr.sin_family = AF_INET; #ifdef HAVE_SIN_LEN addr.sin_len = sizeof(struct sockaddr_in); #endif addr.sin_addr.s_addr = inet_addr(argv[3]); addr.sin_port = htons(atoi(argv[4])); if (usrsctp_connect(sock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0) { perror("connect"); } printf("Connected to %s:%d.\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); } else if (argc == 4) { struct socket *conn_sock; /* operating as server */ memset(&addr, 0, sizeof(struct sockaddr_in)); addr.sin_family = AF_INET; #ifdef HAVE_SIN_LEN addr.sin_len = sizeof(struct sockaddr_in); #endif addr.sin_addr.s_addr = INADDR_ANY; addr.sin_port = htons(atoi(argv[3])); if (usrsctp_bind(sock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0) { perror("bind"); } if (usrsctp_listen(sock, 1) < 0) { perror("listen"); } addr_len = (socklen_t)sizeof(struct sockaddr_in); memset(&addr, 0, sizeof(struct sockaddr_in)); if ((conn_sock = usrsctp_accept(sock, (struct sockaddr *)&addr, &addr_len)) == NULL) { perror("accept"); } usrsctp_close(sock); sock = conn_sock; printf("Connected to %s:%d.\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); } else { printf("Usage: %s local_udp_port remote_udp_port local_port when operating as server\n" " %s local_udp_port remote_udp_port remote_addr remote_port when operating as client\n", argv[0], argv[0]); return (0); } lock_peer_connection(&peer_connection); peer_connection.sock = sock; unlock_peer_connection(&peer_connection); for (;;) { #ifdef _WIN32 if (gets_s(line, LINE_LENGTH) == NULL) { #else if (fgets(line, LINE_LENGTH, stdin) == NULL) { #endif if (usrsctp_shutdown(sock, SHUT_WR) < 0) { perror("usrsctp_shutdown"); } while (usrsctp_finish() != 0) { #ifdef _WIN32 Sleep(1000); #else sleep(1); #endif } break; } if (strncmp(line, "?", strlen("?")) == 0 || strncmp(line, "help", strlen("help")) == 0) { printf("Commands:\n" "open unordered pr_policy pr_value - opens a channel\n" "close channel - closes the channel\n" "send channel:string - sends string using channel\n" "status - prints the status\n" "sleep n - sleep for n seconds\n" "help - this message\n"); } else if (strncmp(line, "status", strlen("status")) == 0) { lock_peer_connection(&peer_connection); print_status(&peer_connection); unlock_peer_connection(&peer_connection); } else if (strncmp(line, "quit", strlen("quit")) == 0) { if (usrsctp_shutdown(sock, SHUT_WR) < 0) { perror("usrsctp_shutdown"); } while (usrsctp_finish() != 0) { #ifdef _WIN32 Sleep(1000); #else sleep(1); #endif } break; } else if (sscanf(line, "open %u %u %u", &unordered, &policy, &value) == 3) { lock_peer_connection(&peer_connection); channel = open_channel(&peer_connection, (uint8_t)unordered, (uint16_t)policy, (uint32_t)value); unlock_peer_connection(&peer_connection); if (channel == NULL) { printf("Creating channel failed.\n"); } else { printf("Channel with id %u created.\n", channel->id); } } else if (sscanf(line, "close %u", &id) == 1) { if (id < NUMBER_OF_CHANNELS) { lock_peer_connection(&peer_connection); close_channel(&peer_connection, &peer_connection.channels[id]); unlock_peer_connection(&peer_connection); } } else if (sscanf(line, "send %u", &id) == 1) { if (id < NUMBER_OF_CHANNELS) { char *msg; msg = strstr(line, ":"); if (msg) { msg++; lock_peer_connection(&peer_connection); #ifdef _WIN32 if (send_user_message(&peer_connection, &peer_connection.channels[id], msg, strlen(msg))) { #else if (send_user_message(&peer_connection, &peer_connection.channels[id], msg, strlen(msg) - 1)) { #endif printf("Message sent.\n"); } else { printf("Message sending failed.\n"); } unlock_peer_connection(&peer_connection); } } } else if (sscanf(line, "sleep %u", &seconds) == 1) { #ifdef _WIN32 Sleep(seconds * 1000); #else sleep(seconds); #endif } else { printf("Unknown command: %s", line); } } return (0); }