/* make an UDP client connection to a host Inputs: <host> the host, host==NULL means broadcast <port> the port # Outputs: <serv_addr> the info of the client Return: the socket */ int udp_make_client(char *host, int port, struct sockaddr_in *serv_addr) { int fd; unsigned int ip; if (host) ip = inet_addr(host); else ip = 0xFFFFFFFF; /* broadcast */ fd = udp_open_socket(ip, port, serv_addr); if (fd > 0) { if (bind_interface(fd, 0, 0)) { /* fail to bind local address for this client */ closesocket(fd); fd = -1; } else { if (!host) { const int val = 1; setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (const char*) &val, sizeof(val)); } dbgprintf ("connected to %s at port %hu", inet_ntoa (serv_addr->sin_addr), port); } } return fd; }
/* call at unbound state */ static int bind_to_usbip(char *busid) { int configvalue = 0; int ninterface = 0; int i; int failed = 0; configvalue = read_bConfigurationValue(busid); ninterface = read_bNumInterfaces(busid); if (configvalue < 0 || ninterface < 0) { dbg("read config and ninf value, removed?"); return -1; } for (i = 0; i < ninterface; i++) { int ret; ret = bind_interface(busid, configvalue, i, USBIP_HOST_DRV_NAME); if (ret < 0) { dbg("bind usbip at %s:%d.%d, failed", busid, configvalue, i); failed = 1; /* need to contine binding at other interfaces */ } } if (failed) return -1; else return 0; }
static int start_instance(AFPacket_Context_t *afpc, AFPacketInstance *instance) { struct packet_mreq mr; int arptype; /* Bind to the specified device so we only see packets from it. */ if (bind_interface(afpc, instance) != 0) return -1; /* Turn on promiscuous mode for the device. */ memset(&mr, 0, sizeof(mr)); mr.mr_ifindex = instance->index; mr.mr_type = PACKET_MR_PROMISC; if (setsockopt(instance->fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr, sizeof(mr)) == -1) { DPE(afpc->errbuf, "%s: setsockopt: %s", __FUNCTION__, strerror(errno)); return -1; } /* Get the link-layer type. */ arptype = iface_get_arptype(instance); if (arptype < 0) { DPE(afpc->errbuf, "%s: failed to get interface type for device %s: (%d) %s", __FUNCTION__, instance->name, errno, strerror(errno)); return -1; } if (arptype != ARPHRD_ETHER) { DPE(afpc->errbuf, "%s: invalid interface type for device %s: %d != %d", __FUNCTION__, instance->name, arptype, ARPHRD_ETHER); return -1; } /* Determine which versions of TPACKET the socket supports. */ if (determine_version(afpc, instance) != DAQ_SUCCESS) return -1; if (afpc->debug) { printf("Version: %u\n", instance->tp_version); printf("Header Length: %u\n", instance->tp_hdrlen); } if (create_rx_ring(afpc, instance) != DAQ_SUCCESS) return -1; if (set_up_rx_ring(afpc, instance) != DAQ_SUCCESS) return -1; return 0; }
/* create a client connection to a specified host Inputs: <iface> the network interface that the server binds <port> the listening port Returns: -1 on failure, otherwise the socket */ int tcp_startup_server(unsigned int iface, int port) { int sockfd; /* create a socket */ sockfd = tcp_open_socket (1); if (sockfd < 0) return -1; /* bind the socket on to a specified interface */ if (bind_interface (sockfd, iface, port) == -1) return -2; if (listen (sockfd, 5) < 0) return -3; dbgprintf ("startup a TCP server %s at port %d fd %d",iptoa (iface),port, sockfd); return sockfd; }
SOCKET make_tcp_connection(const char *host, unsigned short port, unsigned int *ip) { struct sockaddr_in sin; SOCKET f; memset(&sin, 0, sizeof(sin)); sin.sin_port = htons(port); sin.sin_family = AF_INET; if((sin.sin_addr.s_addr = lookup_ip(host)) == 0) return INVALID_SOCKET; if(ip) *ip = sin.sin_addr.s_addr; if((f = new_tcp_socket(ON_NONBLOCKING)) == INVALID_SOCKET) return INVALID_SOCKET; /* if an interface was specify, bind to it before connecting */ if(global.iface) bind_interface(f, global.iface, 0); /* turn on TCP/IP keepalive messages */ set_keepalive(f, 1); log_message_level(LOG_LEVEL_DEBUG, "make_tcp_connection: connecting to %s:%hu", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); if(connect(f, (struct sockaddr *) &sin, sizeof(sin)) < 0) { if(N_ERRNO != EINPROGRESS #ifdef WIN32 /* winsock returns EWOULDBLOCK even in nonblocking mode! ugh!!! */ && N_ERRNO != EWOULDBLOCK #endif ) { nlogerr("make_tcp_connection", "connect"); CLOSE(f); return INVALID_SOCKET; } log_message_level(LOG_LEVEL_SERVER, "make_tcp_connection: connection to %s in progress", host); } else log_message_level(LOG_LEVEL_SERVER, "make_tcp_connection: connection established to %s", host); return f; }
/* start an UDP server at a port Inputs: <iface> the binding address <port> the port # <serv_addr> the info of the server Return: the socket */ int udp_startup_server(unsigned int iface, int port, struct sockaddr_in *serv_addr) { int fd; fd = udp_open_socket(0, port, serv_addr); if (fd > 0) { if (bind_interface(fd, iface, port)) { /* fail to bind to local */ closesocket(fd); fd = -1; } else { serv_addr->sin_addr.s_addr = iface? iface:lookup_localhost_ip(); /* host ip */ dbgprintf ("startup a UDP server at port %d fd %d",port,fd); } } return fd; }
void http_tracker_connection::start() { // TODO: authentication std::string url = tracker_req().url; if (tracker_req().kind == tracker_request::scrape_request) { // find and replace "announce" with "scrape" // in request std::size_t pos = url.find("announce"); if (pos == std::string::npos) { m_ios.post(boost::bind(&http_tracker_connection::fail_disp, self() , error_code(errors::scrape_not_available))); return; } url.replace(pos, 8, "scrape"); } #if TORRENT_USE_I2P bool i2p = is_i2p_url(url); #else static const bool i2p = false; #endif session_settings const& settings = m_ses.settings(); // if request-string already contains // some parameters, append an ampersand instead // of a question mark size_t arguments_start = url.find('?'); if (arguments_start != std::string::npos) url += "&"; else url += "?"; url += "info_hash="; url += escape_string((const char*)&tracker_req().info_hash[0], 20); if (tracker_req().kind == tracker_request::announce_request) { char str[1024]; const bool stats = tracker_req().send_stats; snprintf(str, sizeof(str), "&peer_id=%s&port=%d&uploaded=%"PRId64 "&downloaded=%"PRId64"&left=%"PRId64"&corrupt=%"PRId64"&redundant=%"PRId64 "&compact=1&numwant=%d&key=%x&no_peer_id=1" , escape_string((const char*)&tracker_req().pid[0], 20).c_str() // the i2p tracker seems to verify that the port is not 0, // even though it ignores it otherwise , i2p ? 1 : tracker_req().listen_port , stats ? tracker_req().uploaded : 0 , stats ? tracker_req().downloaded : 0 , stats ? tracker_req().left : 0 , stats ? tracker_req().corrupt : 0 , stats ? tracker_req().redundant: 0 , tracker_req().num_want , tracker_req().key); url += str; #ifndef TORRENT_DISABLE_ENCRYPTION if (m_ses.get_pe_settings().in_enc_policy != pe_settings::disabled) url += "&supportcrypto=1"; #endif if (!tracker_req().trackerid.empty()) { std::string id = tracker_req().trackerid; url += "&trackerid="; url += escape_string(id.c_str(), id.length()); } if (tracker_req().event != tracker_request::none) { const char* event_string[] = {"completed", "started", "stopped", "paused"}; url += "&event="; url += event_string[tracker_req().event - 1]; } #if TORRENT_USE_I2P if (i2p) { url += "&ip="; url += escape_string(m_i2p_conn->local_endpoint().c_str() , m_i2p_conn->local_endpoint().size()); url += ".i2p"; } else #endif if (!m_ses.settings().anonymous_mode) { if (!settings.announce_ip.empty()) { url += "&ip=" + escape_string( settings.announce_ip.c_str(), settings.announce_ip.size()); } else if (m_ses.settings().announce_double_nat && is_local(m_ses.listen_address())) { // only use the global external listen address here // if it turned out to be on a local network // since otherwise the tracker should use our // source IP to determine our origin url += "&ip=" + print_address(m_ses.listen_address()); } if (!tracker_req().ipv6.empty() && !i2p) { url += "&ipv6="; url += tracker_req().ipv6; } if (!tracker_req().ipv4.empty() && !i2p) { url += "&ipv4="; url += tracker_req().ipv4; } } } m_tracker_connection.reset(new http_connection(m_ios, m_cc , boost::bind(&http_tracker_connection::on_response, self(), _1, _2, _3, _4) , true , boost::bind(&http_tracker_connection::on_connect, self(), _1) , boost::bind(&http_tracker_connection::on_filter, self(), _1, _2) #ifdef TORRENT_USE_OPENSSL , tracker_req().ssl_ctx #endif )); int timeout = tracker_req().event==tracker_request::stopped ?settings.stop_tracker_timeout :settings.tracker_completion_timeout; m_tracker_connection->get(url, seconds(timeout) , tracker_req().event == tracker_request::stopped ? 2 : 1 , &m_ps, 5, settings.anonymous_mode ? "" : settings.user_agent , bind_interface() #if TORRENT_USE_I2P , m_i2p_conn #endif ); // the url + 100 estimated header size sent_bytes(url.size() + 100); #if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) boost::shared_ptr<request_callback> cb = requester(); if (cb) { cb->debug_log("==> TRACKER_REQUEST [ url: " + url + " ]"); } #endif }
void http_tracker_connection::start() { // TODO: authentication std::string url = tracker_req().url; //feeqi add validation param std::string feeqi_auth = ""; if (tracker_req().kind == tracker_request::scrape_request) { // find and replace "announce" with "scrape" // in request std::size_t pos = url.find("announce"); if (pos == std::string::npos) { m_ios.post(boost::bind(&http_tracker_connection::fail_disp, self() , -1, "scrape is not available on url: '" + tracker_req().url +"'")); return; } url.replace(pos, 8, "scrape"); } session_settings const& settings = m_ses.settings(); // if request-string already contains // some parameters, append an ampersand instead // of a question mark size_t arguments_start = url.find('?'); if (arguments_start != std::string::npos) url += "&"; else url += "?"; url += "info_hash="; url += escape_string((const char*)&tracker_req().info_hash[0], 20); if (tracker_req().kind == tracker_request::announce_request) { char str[1024]; const bool stats = tracker_req().send_stats; snprintf(str, sizeof(str), "&peer_id=%s&port=%d&uploaded=%"PRId64 "&downloaded=%"PRId64"&left=%"PRId64"&corrupt=%"PRId64"&redundant=%"PRId64 "&compact=1&numwant=%d&key=%x&no_peer_id=1" , escape_string((const char*)&tracker_req().pid[0], 20).c_str() , tracker_req().listen_port , stats ? tracker_req().uploaded : 0 , stats ? tracker_req().downloaded : 0 , stats ? tracker_req().left : 0 , stats ? tracker_req().corrupt : 0 , stats ? tracker_req().redundant: 0 , tracker_req().num_want , tracker_req().key); url += str; #ifndef TORRENT_DISABLE_ENCRYPTION if (m_ses.get_pe_settings().in_enc_policy != pe_settings::disabled) url += "&supportcrypto=1"; #endif if (tracker_req().event != tracker_request::none) { const char* event_string[] = {"completed", "started", "stopped"}; url += "&event="; url += event_string[tracker_req().event - 1]; } if (settings.announce_ip != address()) { error_code ec; std::string ip = settings.announce_ip.to_string(ec); if (!ec) url += "&ip=" + ip; } if (!tracker_req().ipv6.empty()) { url += "&ipv6="; url += tracker_req().ipv6; } if (!tracker_req().ipv4.empty()) { url += "&ipv4="; url += tracker_req().ipv4; } } //feeqi add validation param feeqi_auth += escape_string((const char*)&tracker_req().info_hash[0], 1); feeqi_auth += escape_string((const char*)&tracker_req().pid[0], 1); url += "&feeqi_auth="; url += feeqi_auth; url += "%3d%3d"; m_tracker_connection.reset(new http_connection(m_ios, m_cc , boost::bind(&http_tracker_connection::on_response, self(), _1, _2, _3, _4) , true , boost::bind(&http_tracker_connection::on_connect, self(), _1) , boost::bind(&http_tracker_connection::on_filter, self(), _1, _2))); int timeout = tracker_req().event==tracker_request::stopped ?settings.stop_tracker_timeout :settings.tracker_completion_timeout; m_tracker_connection->get(url, seconds(timeout) , tracker_req().event == tracker_request::stopped ? 2 : 1 , &m_ps, 5, settings.user_agent, bind_interface()); // the url + 100 estimated header size sent_bytes(url.size() + 100); #if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) boost::shared_ptr<request_callback> cb = requester(); if (cb) { cb->debug_log("==> TRACKER_REQUEST [ url: " + url + " ]"); } #endif }
double get_average_delay(char* server_ip,char* host_domain,char* interface_name) { /* socket init */ int sockfd; struct sockaddr_in dest_addr; dest_addr.sin_family = AF_INET; dest_addr.sin_port = htons(HTTP_PORT); dest_addr.sin_addr.s_addr = inet_addr(server_ip); /* create socket*/ if((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0){ IK_APP_ERR_LOG("ik_speed delay socket() %s\n",strerror(errno)); return MIN_DELAY; } /* bind choice */ if(bind_fd == 1){ bind_interface(interface_name,sockfd); } /*connect timeout set time */ struct timeval timeo = {TIME_OUT_TIME-5,0}; socklen_t len = sizeof(timeo); if(setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &timeo, len) == -1){ IK_APP_ERR_LOG("ik_speed delay SO_SNDTIMEO setsockopt() %s\n",strerror(errno)); return MIN_DELAY; } /* change recv buf */ int rcvbuf_len=512*1024; socklen_t int_len = sizeof(int); if(getsockopt(sockfd,SOL_SOCKET,SO_RCVBUF,(void*)&rcvbuf_len,&int_len) < 0 ){ return -1; } printf("the recevice buf len: %d\n", rcvbuf_len ); char buffer[BUF_SIZE]; char recv_buffer[BUF_SIZE]; fill_latency_request(buffer,host_domain); /* http connect to server ip */ int connect_res = connect(sockfd,(struct sockaddr *)&dest_addr,sizeof(dest_addr)); if(connect_res == -1){ IK_APP_ERR_LOG("ik_speed %s delay connect\n",strerror(errno)); return MIN_DELAY; } /*set recv time out time */ if(setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeo, len) == -1){ IK_APP_ERR_LOG("ik_speed delay SO_RCVTIMEO setsockopt() %s\n",strerror(errno)); return MIN_DELAY; } /*delay time */ struct timeval starttime,endtime; double average_time = 0; /*get delay*/ int sendlen = strlen(buffer); int i,nSend,nRecv; for(i=0;i<1;i++){ gettimeofday(&starttime,0); nSend = send(sockfd,buffer,sendlen,0); if(nSend<0){ IK_APP_ERR_LOG("ik_speed delay test send() %s\n",strerror(errno)); close(sockfd); return MIN_DELAY; } nRecv = recv(sockfd,recv_buffer,sendlen,0); if(nRecv<0){ IK_APP_ERR_LOG("ik_speed delay test recv() %s\n",strerror(errno)); close(sockfd); return MIN_DELAY; } gettimeofday(&endtime,0); double timeuse = 1000000*(endtime.tv_sec - starttime.tv_sec) + endtime.tv_usec - starttime.tv_usec; average_time += timeuse; } close(sockfd); if(average_time<=0){ IK_APP_ERR_LOG("ik_speed failed to get delay time \n"); return MIN_DELAY; } return average_time; }
void* file_download(void *arg) { struct download_post_info *info; info = (struct download_post_info *)arg; long long recv_lens_sum=0; /* socket init */ int sockfd; struct sockaddr_in dest_addr; dest_addr.sin_family = AF_INET; dest_addr.sin_port = htons(HTTP_PORT); dest_addr.sin_addr.s_addr = inet_addr(info->server_ip); /* create socket*/ if((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0){ IK_APP_ERR_LOG("ik_speed failed create socket in download speed \n"); goto pend; } /* bind choice */ if(bind_fd == 1){ if(bind_interface(info->interface,sockfd)==1){ goto pend; } } /*connect timeout set time */ struct timeval timeo = {TIME_OUT_MIN,0}; socklen_t len = sizeof(timeo); if(setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &timeo, len) == -1){ IK_APP_ERR_LOG("ik_speed setsockopt() set timeout %s\n",strerror(errno)); goto pend; } /* http connect to server ip */ int connect_res = connect(sockfd,(struct sockaddr *)&dest_addr,sizeof(dest_addr)); if(connect_res == -1){ IK_APP_ERR_LOG("ik_speed download connect() %s\n",strerror(errno)); goto pend;; } /*set recv time out time */ if(setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeo, len) == -1){ IK_APP_ERR_LOG("ik_speed download recv %s\n",strerror(errno)); goto pend; } /*get delay*/ int nSend,nRecv; int sendlen = strlen(info->post_string); nSend = send(sockfd,info->post_string,sendlen,0); if(nSend<0){ IK_APP_ERR_LOG("download send() %s",strerror(errno)); goto pend; } char read_buf[READ_BUF]; while(1){ nRecv = recv(sockfd,read_buf,READ_BUF,0); if(nRecv<0){ if(errno==EAGAIN){ IK_APP_ERR_LOG("ik_speed recv() %s\n",strerror(errno)); } goto pend; } if(0 == nRecv) break; recv_lens_sum += nRecv; /*make the last pthread end more faster*/ if(nRecv<4096&&pool->cur_queue_size==0) break; } pend: //printf("thread recv : %lld\n",recv_lens_sum); pthread_mutex_lock (&(pool->queue_lock)); sum_lens += recv_lens_sum; pthread_mutex_unlock (&(pool->queue_lock)); close(sockfd); return NULL; }
void* file_upload(void *arg) { struct download_post_info *info; info = (struct download_post_info *)arg; int i = 0,seek; int size = 250*100*100; int loop_num = size / (36*30); char * chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; char * first_one = "content1=0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; int first_len = strlen(first_one); char post_string[SEND_BUF+1]; long long send_sum = 0; bzero(post_string,(SEND_BUF+1)); for(i=0;i<30;i++){ seek = i*36; snprintf((post_string+seek),SEND_BUF,"%s",chars); } int post_string_len = strlen(post_string); /* socket init */ int sockfd; struct sockaddr_in dest_addr; dest_addr.sin_family = AF_INET; dest_addr.sin_port = htons(HTTP_PORT); dest_addr.sin_addr.s_addr = inet_addr(info->server_ip); /* create socket*/ if((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0){ IK_APP_ERR_LOG("ik_speed upload socket() %s\n",strerror(errno)); goto psend; } /* bind choice */ if(bind_fd == 1){ if(bind_interface(info->interface,sockfd)==1){ goto psend; } } /*connect timeout set time */ struct timeval timeo = {TIME_OUT_MIN,0}; socklen_t len = sizeof(timeo); if(setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &timeo, len) == -1){ IK_APP_ERR_LOG("ik_speed upload setsockopt() %s \n",strerror(errno)); goto psend; } /* http connect to server ip */ int connect_res = connect(sockfd,(struct sockaddr *)&dest_addr,sizeof(dest_addr)); if(connect_res == -1){ IK_APP_ERR_LOG("ik_speed upload connect() %s\n",strerror(errno)); goto psend;; } /*set recv time out time */ if(setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeo, len) == -1){ IK_APP_ERR_LOG("ik_speed upload setsockopt() %s\n",strerror(errno)); write_result(info->interface,"线程 设置接受超时时间失败"); goto psend; } /*get upload delay*/ int nSend,nRecv; int head_sendlen = strlen(info->post_string); nSend = send(sockfd,info->post_string,head_sendlen,0); if(nSend<0){ write_result(info->interface," upload 线程发送数据包失败"); goto psend; } send_sum += nSend; nSend = send(sockfd,first_one,first_len,0); if(nSend<0){ write_result(info->interface," upload 线程发送数据包失败"); goto psend; } //send_sum = head_sendlen + first_len; send_sum += nSend; /*send post string */ for(i=1;i<loop_num;i++){ nSend = send(sockfd,post_string,post_string_len,0); if(nSend<0){ IK_APP_ERR_LOG("ik_speed upload send() %s\n",strerror(errno)); goto psend; } //send_sum += post_string_len; send_sum += nSend; } char read_buf[20]; nRecv = recv(sockfd,read_buf,11,0); if(nRecv<0){ IK_APP_ERR_LOG("ik_speed upload recv %s\n",strerror(errno)); goto psend; } psend: //printf("thread send : %lld\n",send_sum); pthread_mutex_lock (&(pool->queue_lock)); sum_send_lens += send_sum; pthread_mutex_unlock (&(pool->queue_lock)); close(sockfd); return NULL; }
void http_tracker_connection::start() { std::string url = tracker_req().url; if (0 != (tracker_req().kind & tracker_request::scrape_request)) { // find and replace "announce" with "scrape" // in request std::size_t pos = url.find("announce"); if (pos == std::string::npos) { tracker_connection::fail(error_code(errors::scrape_not_available)); return; } url.replace(pos, 8, "scrape"); } #if TORRENT_USE_I2P bool i2p = is_i2p_url(url); #else static const bool i2p = false; #endif aux::session_settings const& settings = m_man.settings(); // if request-string already contains // some parameters, append an ampersand instead // of a question mark size_t arguments_start = url.find('?'); if (arguments_start != std::string::npos) url += "&"; else url += "?"; url += "info_hash="; url += escape_string(tracker_req().info_hash.data(), 20); if (0 == (tracker_req().kind & tracker_request::scrape_request)) { const char* event_string[] = {"completed", "started", "stopped", "paused"}; char str[1024]; const bool stats = tracker_req().send_stats; snprintf(str, sizeof(str) , "&peer_id=%s" "&port=%d" "&uploaded=%" PRId64 "&downloaded=%" PRId64 "&left=%" PRId64 "&corrupt=%" PRId64 "&key=%08X" "%s%s" // event "&numwant=%d" "&compact=1" "&no_peer_id=1" , escape_string(tracker_req().pid.data(), 20).c_str() // the i2p tracker seems to verify that the port is not 0, // even though it ignores it otherwise , i2p ? 1 : tracker_req().listen_port , stats ? tracker_req().uploaded : 0 , stats ? tracker_req().downloaded : 0 , stats ? tracker_req().left : 0 , stats ? tracker_req().corrupt : 0 , tracker_req().key , (tracker_req().event != tracker_request::none) ? "&event=" : "" , (tracker_req().event != tracker_request::none) ? event_string[tracker_req().event - 1] : "" , tracker_req().num_want); url += str; #if !defined(TORRENT_DISABLE_ENCRYPTION) && !defined(TORRENT_DISABLE_EXTENSIONS) if (settings.get_int(settings_pack::in_enc_policy) != settings_pack::pe_disabled && settings.get_bool(settings_pack::announce_crypto_support)) url += "&supportcrypto=1"; #endif if (stats && settings.get_bool(settings_pack::report_redundant_bytes)) { url += "&redundant="; url += to_string(tracker_req().redundant).elems; } if (!tracker_req().trackerid.empty()) { std::string id = tracker_req().trackerid; url += "&trackerid="; url += escape_string(id.c_str(), id.length()); } #if TORRENT_USE_I2P if (i2p && tracker_req().i2pconn) { if (tracker_req().i2pconn->local_endpoint().empty()) { fail(error_code(errors::no_i2p_endpoint), -1, "Waiting for i2p acceptor from SAM bridge", 5); return; } else { url += "&ip=" + tracker_req ().i2pconn->local_endpoint () + ".i2p"; } } else #endif if (!settings.get_bool(settings_pack::anonymous_mode)) { std::string announce_ip = settings.get_str(settings_pack::announce_ip); if (!announce_ip.empty()) { url += "&ip=" + escape_string(announce_ip.c_str(), announce_ip.size()); } // TODO: support this somehow /* else if (settings.get_bool(settings_pack::announce_double_nat) && is_local(m_ses.listen_address())) { // only use the global external listen address here // if it turned out to be on a local network // since otherwise the tracker should use our // source IP to determine our origin url += "&ip=" + print_address(m_ses.listen_address()); } */ } } m_tracker_connection.reset(new http_connection(get_io_service(), m_man.host_resolver() , boost::bind(&http_tracker_connection::on_response, shared_from_this(), _1, _2, _3, _4) , true, settings.get_int(settings_pack::max_http_recv_buffer_size) , boost::bind(&http_tracker_connection::on_connect, shared_from_this(), _1) , boost::bind(&http_tracker_connection::on_filter, shared_from_this(), _1, _2) #ifdef TORRENT_USE_OPENSSL , tracker_req().ssl_ctx #endif )); int timeout = tracker_req().event==tracker_request::stopped ?settings.get_int(settings_pack::stop_tracker_timeout) :settings.get_int(settings_pack::tracker_completion_timeout); // when sending stopped requests, prefer the cached DNS entry // to avoid being blocked for slow or failing responses. Chances // are that we're shutting down, and this should be a best-effort // attempt. It's not worth stalling shutdown. aux::proxy_settings ps(settings); m_tracker_connection->get(url, seconds(timeout) , tracker_req().event == tracker_request::stopped ? 2 : 1 , ps.proxy_tracker_connections ? &ps : NULL , 5, settings.get_bool(settings_pack::anonymous_mode) ? "" : settings.get_str(settings_pack::user_agent) , bind_interface() , tracker_req().event == tracker_request::stopped ? resolver_interface::prefer_cache : resolver_interface::abort_on_shutdown , tracker_req().auth #if TORRENT_USE_I2P , tracker_req().i2pconn #endif ); // the url + 100 estimated header size sent_bytes(url.size() + 100); #ifndef TORRENT_DISABLE_LOGGING boost::shared_ptr<request_callback> cb = requester(); if (cb) { cb->debug_log("==> TRACKER_REQUEST [ url: %s ]", url.c_str()); } #endif }