static void handle_query(struct cfg *cf, int fd, struct sockaddr_storage *raddr, socklen_t rlen, char *cookie, struct rtpp_session *spa, int idx) { char buf[1024 * 8]; int len; if (cookie != NULL) { len = sprintf(buf, "%s %d %lu %lu %lu %lu\n", cookie, get_ttl(spa), spa->pcount[idx], spa->pcount[NOT(idx)], spa->pcount[2], spa->pcount[3]); } else { len = sprintf(buf, "%d %lu %lu %lu %lu\n", get_ttl(spa), spa->pcount[idx], spa->pcount[NOT(idx)], spa->pcount[2], spa->pcount[3]); } doreply(cf, fd, buf, len, raddr, rlen); }
static void handle_query(struct cfg *cf, int fd, struct rtpp_command *cmd, struct rtpp_session *spa, int idx) { char buf[1024 * 8]; int len; if (cmd->cookie != NULL) { len = sprintf(buf, "%s %d %lu %lu %lu %lu\n", cmd->cookie, get_ttl(spa), spa->pcount[idx], spa->pcount[NOT(idx)], spa->pcount[2], spa->pcount[3]); } else { len = sprintf(buf, "%d %lu %lu %lu %lu\n", get_ttl(spa), spa->pcount[idx], spa->pcount[NOT(idx)], spa->pcount[2], spa->pcount[3]); } doreply(&cf->stable, fd, buf, len, &cmd->raddr, cmd->rlen); }
bool memcache_session::set_attrs(const std::map<string, session_string>& attrs) { const char* sid = get_sid(); if (sid == NULL || *sid == 0) return false; string buf; serialize(attrs, buf); // 序列化数据 time_t ttl = get_ttl(); return cache_->set(sid, buf.c_str(), buf.length(), ttl); }
void send_insertion_packet(struct send_tcp_vars *vars, unsigned int flags) { if (flags & INS_DISC_SMALL_TTL) { unsigned char ttl = get_ttl(str2ip(vars->dst_ip)); vars->ttl = ttl - 3; } if (flags & INS_DISC_BAD_TCP_CHECKSUM) { vars->wrong_tcp_checksum = 1; } if (flags & INS_DISC_NO_TCP_FLAG) { // this will override existing flags vars->flags = 0; } if (flags & INS_DISC_BAD_ACK_NUM) { // ack number in the future, is it good for all cases? vars->ack_num + 100000; } if (flags & INS_DISC_MD5) { u_char bytes[20] = {0x13,0x12,0xf9,0x89,0x5c,0xdd,0xa6,0x15,0x12,0x83,0x3e,0x93,0x11,0x22,0x33,0x44,0x55,0x66,0x01,0x01}; memcpy(vars->tcp_opt + vars->tcp_opt_len, bytes, 20); vars->tcp_opt_len += 20; } if (flags & INS_DISC_OLD_TIMESTAMP) { // check if there's timestamp int i; for (i = 0; i < vars->tcp_opt_len; i++) { unsigned char kind = vars->tcp_opt[i]; if (kind == 1) continue; // padding unsigned char len = vars->tcp_opt[i + 1]; if (kind == 8) // Timestamp { unsigned int *tsval = (unsigned int*)(vars->tcp_opt + i + 2); *tsval = htonl(ntohl(*tsval) - 10000); break; } else { i += len; } } } //dump_send_tcp_vars(vars); send_tcp(vars); }
int x18_process_request(struct mypacket *packet) { char sip[16], dip[16]; unsigned short sport, dport; struct in_addr s_in_addr = {packet->iphdr->saddr}; struct in_addr d_in_addr = {packet->iphdr->daddr}; strncpy(sip, inet_ntoa(s_in_addr), 16); strncpy(dip, inet_ntoa(d_in_addr), 16); sport = ntohs(packet->tcphdr->th_sport); dport = ntohs(packet->tcphdr->th_dport); int ttl = get_ttl(str2ip(dip)); log_debug("[TTL Probing] The probed TTL value for %s is %d.", dip, ttl); return 0; }
int x34_process_synack(struct mypacket *packet) { char sip[16], dip[16]; unsigned short sport, dport; struct in_addr s_in_addr = {packet->iphdr->saddr}; struct in_addr d_in_addr = {packet->iphdr->daddr}; strncpy(sip, inet_ntoa(s_in_addr), 16); strncpy(dip, inet_ntoa(d_in_addr), 16); sport = ntohs(packet->tcphdr->th_sport); dport = ntohs(packet->tcphdr->th_dport); unsigned char ttl = get_ttl(str2ip(sip)); log_debug("The probed TTL value is %d.", ttl); ttl -= 2; // to not reach server send_RST_super(dip, dport, sip, sport, packet->tcphdr->th_ack, ttl); usleep(30000); send_RST_super(dip, dport, sip, sport, packet->tcphdr->th_ack, ttl); usleep(30000); send_RST_super(dip, dport, sip, sport, packet->tcphdr->th_ack, ttl); return 1; }
static void process_rtp(struct cfg *cf, double dtime, int alarm_tick) { int readyfd, skipfd, ridx; struct rtpp_session *sp; struct rtp_packet *packet; /* Relay RTP/RTCP */ skipfd = 0; pthread_mutex_lock(&cf->sessinfo.lock); for (readyfd = 0; readyfd < cf->sessinfo.nsessions; readyfd++) { sp = cf->sessinfo.sessions[readyfd]; if (alarm_tick != 0 && sp != NULL && sp->rtcp != NULL && sp->sidx[0] == readyfd) { if (get_ttl(sp) == 0) { rtpp_log_write(RTPP_LOG_INFO, sp->log, "session timeout"); rtpp_notify_schedule(cf, sp); remove_session(cf, sp); } else { if (sp->ttl[0] != 0) sp->ttl[0]--; if (sp->ttl[1] != 0) sp->ttl[1]--; } } if (cf->sessinfo.pfds[readyfd].fd == -1) { /* Deleted session, count and move one */ skipfd++; continue; } /* Find index of the call leg within a session */ for (ridx = 0; ridx < 2; ridx++) if (cf->sessinfo.pfds[readyfd].fd == sp->fds[ridx]) break; /* * Can't happen. */ assert(ridx != 2); /* Compact pfds[] and sessions[] by eliminating removed sessions */ if (skipfd > 0) { cf->sessinfo.pfds[readyfd - skipfd] = cf->sessinfo.pfds[readyfd]; cf->sessinfo.sessions[readyfd - skipfd] = cf->sessinfo.sessions[readyfd]; sp->sidx[ridx] = readyfd - skipfd; } if (sp->complete != 0) { if ((cf->sessinfo.pfds[readyfd].revents & POLLIN) != 0) rxmit_packets(cf, sp, ridx, dtime); if (sp->resizers[ridx].output_nsamples > 0) { while ((packet = rtp_resizer_get(&sp->resizers[ridx], dtime)) != NULL) { send_packet(cf, sp, ridx, packet); rtp_packet_free(packet); } } } } /* Trim any deleted sessions at the end */ cf->sessinfo.nsessions -= skipfd; pthread_mutex_unlock(&cf->sessinfo.lock); }
/***************************************************************** ** parsezonefile () ** parse the BIND zone file 'file' and store the minimum and ** maximum ttl value in the corresponding parameter. ** if keydbfile is set, check if this file is already include. ** if inclfiles is not NULL store a list of included files names ** in it. ** return 0 if keydbfile is not included ** return 1 if keydbfile is included ** return -1 on error *****************************************************************/ int parsezonefile (const char *file, long *pminttl, long *pmaxttl, const char *keydbfile, char *inclfiles, size_t *plen) { FILE *infp; int len; int lnr; long ttl; int multi_line_rr; int keydbfilefound; char buf[1024]; const char *p; assert (file != NULL); assert (pminttl != NULL); assert (pmaxttl != NULL); dbg_val4 ("parsezonefile (\"%s\", %ld, %ld, \"%s\")\n", file, *pminttl, *pmaxttl, keydbfile); if ( (infp = fopen (file, "r")) == NULL ) { error ("parsezonefile: couldn't open file \"%s\" for input\n", file); return -1; } lnr = 0; keydbfilefound = 0; multi_line_rr = 0; while ( fgets (buf, sizeof buf, infp) != NULL ) { len = strlen (buf); if ( buf[len-1] != '\n' ) /* line too long ? */ fprintf (stderr, "line too long\n"); lnr++; p = buf; if ( multi_line_rr ) /* skip line if it's part of a multiline rr */ { is_multiline_rr (&multi_line_rr, p); continue; } if ( *p == '$' ) /* special directive ? */ { if ( strncmp (p+1, "TTL", 3) == 0 ) /* $TTL ? */ { ttl = get_ttl (p+4); dbg_val3 ("%s:%d:ttl %ld\n", file, lnr, ttl); setminmax (pminttl, ttl, pmaxttl); } else if ( strncmp (p+1, "INCLUDE", 7) == 0 ) /* $INCLUDE ? */ { char fname[30+1]; sscanf (p+9, "%30s", fname); dbg_val ("$INCLUDE directive for file \"%s\" found\n", fname); if ( strcmp (fname, keydbfile) == 0 ) keydbfilefound = 1; else { if ( inclfiles && plen ) { len = snprintf (inclfiles, *plen, ",%s", fname); if ( *plen <= len ) /* no space left in include file string */ return keydbfilefound; inclfiles += len; *plen -= len; } int ret = parsezonefile (fname, pminttl, pmaxttl, keydbfile, inclfiles, plen); if ( ret ) /* keydb found or read error ? */ keydbfilefound = ret; } } } else if ( !isspace (*p) ) /* label ? */ p = skiplabel (p); p = skipws (p); if ( *p == ';' ) /* skip line if it's a comment line */ continue; /* skip class (hesiod is not supported now) */ if ( (toupper (*p) == 'I' && toupper (p[1]) == 'N') || (toupper (*p) == 'C' && toupper (p[1]) == 'H') ) p += 2; p = skipws (p); if ( isdigit (*p) ) /* ttl ? */ { ttl = get_ttl (p); dbg_val3 ("%s:%d:ttl %ld\n", file, lnr, ttl); setminmax (pminttl, ttl, pmaxttl); } /* check the rest of the line if it's the beginning of a multi_line_rr */ is_multiline_rr (&multi_line_rr, p); } if ( file ) fclose (infp); dbg_val5 ("parsezonefile (\"%s\", %ld, %ld, \"%s\") ==> %d\n", file, *pminttl, *pmaxttl, keydbfile, keydbfilefound); return keydbfilefound; }
/* Process TCP packets * Return 0 to accept packet, otherwise to drop packet */ int process_tcp_packet(struct mypacket *packet, char inout) { int ret = 0; struct myiphdr *iphdr = packet->iphdr; struct mytcphdr *tcphdr = packet->tcphdr; unsigned char *payload = packet->payload; char sip[16], dip[16]; ip2str(iphdr->saddr, sip); ip2str(iphdr->daddr, dip); unsigned short sport, dport; //unsigned int seq, ack; sport = ntohs(tcphdr->th_sport); dport = ntohs(tcphdr->th_dport); //seq = tcphdr->th_seq; //ack = tcphdr->th_ack; log_debug("[TCP] This packet goes from %s:%d to %s:%d", sip, sport, dip, dport); log_debug("TCP flags: %s", tcp_flags(tcphdr->th_flags)); struct fourtuple fourtp; fourtp.saddr = iphdr->saddr; fourtp.daddr = iphdr->daddr; fourtp.sport = tcphdr->th_sport; fourtp.dport = tcphdr->th_dport; // for testing uni-directional packet forwarding to bypass IP blocking //if (dport == 80 && is_blocked_ip(dip)) { // log_debug("Going to forward that packet!!!"); // unsigned int newlen = packet->len + 4; // char *newpkt = (char*)malloc(newlen); // memcpy(newpkt, packet->data, packet->len); // *(u_int32_t*)(newpkt + packet->len) = iphdr->daddr; // ip_hdr(newpkt)->daddr = str2ip(PACKET_FORWARDER); // send_raw(newpkt, newlen); // log_debug("sent!!!"); // return 0; //} if (tcphdr->th_flags == TCP_SYN) { // Processing outgoing SYN packet. // Uploading diagnostic log is disabled. (2017.9.1) //if (strcmp(dip, FEEDBACK_SERVER_IP) == 0) // return 0; // choose a strategy for the newly created connection int sid = choose_strategy_by_historical_result(iphdr->daddr); log_debug("Using strategy %s", g_strats[sid].name); set_sid(&fourtp, sid); //cache_strategy(&fourtp, sid); if (g_strats[sid].process_syn) { ret = g_strats[sid].process_syn(packet); #ifndef EVALUATION if (ret) { need_evaluation(&fourtp); } #endif } } if (tcphdr->th_flags == (TCP_SYN | TCP_ACK)) { // Got a SYN-ACK from server // send an ACK with 1 TTL to make home router happy if (opt_inject_ack_with_one_ttl) send_ACK_with_one_ttl(dip, dport, sip, sport, tcphdr->th_ack, htonl(ntohl(tcphdr->th_seq)+1)); struct fourtuple reverse_fourtp; reverse_fourtp.saddr = iphdr->daddr; reverse_fourtp.daddr = iphdr->saddr; reverse_fourtp.sport = tcphdr->th_dport; reverse_fourtp.dport = tcphdr->th_sport; int sid = get_sid(&reverse_fourtp); if (sid >= 0) { if (get_ttl(iphdr->saddr) == 0) { // if TTL hasn't been initialized // find initial TTL from SYN/ACK packet int ttl = choose_appropriate_ttl(iphdr->ttl); set_ttl(iphdr->saddr, ttl); } if (g_strats[sid].process_synack) { ret = g_strats[sid].process_synack(packet); #ifndef EVALUATION if (ret) { need_evaluation(&reverse_fourtp); } #endif } } else if (sid == -1) { ret = process_synack_for_ttl_probing(packet); } //if (opt_inject_syn_and_syn_ack_with_one_ttl) // send_one_ttl_SYN_and_SYN_ACK(dip, dport, sip, sport, tcphdr->th_ack, tcphdr->th_seq); } else if ((tcphdr->th_flags & TCP_ACK) && !(tcphdr->th_flags & (TCP_SYN | TCP_RST))) { // ignore ACK packets without payload if (packet->payload_len == 0) return 0; if (dport == 80) { if ((payload[0] == 'G' && payload[1] == 'E' && payload[2] == 'T' && payload[3] == ' ') || (payload[0] == 'P' && payload[1] == 'O' && payload[2] == 'S' && payload[3] == 'T' && payload[4] == ' ')) { // Got a outgoing HTTP request log_debug("[TCP] Sent a HTTP request from %s:%d to %s:%d.", sip, sport, dip, dport); int i, j, k, l; //char req_line[1000]; //for (i = 0; i < 1000; i++) { // if (payload[i] == '\r' || payload[i] == '\n') { // req_line[i] = 0; // break; // } // req_line[i] = payload[i]; //} // Generate the HTTP request line. Format: GET/POST domain/url. e.g. GET www.google.com/index.php char req_line2[1000]; // copy GET/POST for (i = 0; payload[i] != ' ' && i < packet->payload_len; i++) { req_line2[i] = payload[i]; } req_line2[i++] = ' '; k = i; // find Host field for (j = i; j < packet->payload_len; j++) { if (payload[j] == 'H' && payload[j+1] == 'o' && payload[j+2] == 's' && payload[j+3] == 't' && payload[j+4] == ':' && (payload[j-1] == '\r' || payload[j-1] == '\n')) { j += 5; // copy Host value while (payload[j] == ' ') j++; for (l = 0; l < 99 && j+l < packet->payload_len; l++) { if (payload[j+l] == '\r' || payload[j+l] == '\n') break; req_line2[k++] = payload[j+l]; } break; } } // copy the rest of request line for (; i < 900 && i < packet->payload_len; i++) { if (payload[i] == '\r' || payload[i] == '\n') { break; } req_line2[k++] = payload[i]; } req_line2[k] = 0; log_debug("[TCP] %s", req_line2); int sid = get_sid(&fourtp); if (sid >= 0 && g_strats[sid].process_request) { ret = g_strats[sid].process_request(packet); #ifndef EVALUATION if (ret) { need_evaluation(&fourtp); } #endif } #ifdef EVALUATION if (strstr(req_line2, "ultrasurf") || strstr(req_line2, "goodword")) { need_evaluation(&fourtp); } #endif cache_http_request(&fourtp, req_line2); } } else if (sport == 80) { if (payload[0] == 'H' && payload[1] == 'T' && payload[2] == 'T' && payload[3] == 'P') { // Got a incoming HTTP response log_debug("[TCP] Got a HTTP response from %s:%d to %s:%d.", sip, sport, dip, dport); process_http_response(&fourtp, tcphdr->th_seq, iphdr->ttl); } } else if (dport == 53) { // Got a DNS request over TCP log_debug("[TCP] Sent a DNS request from %s:%d to %s:%d.", sip, sport, dip, dport); int sid = get_sid(&fourtp); if (sid >= 0 && g_strats[sid].process_request) { ret = g_strats[sid].process_request(packet); #ifndef EVALUATION if (ret) { need_evaluation(&fourtp); } #endif } cache_dns_tcp_request(&fourtp); } else if (sport == 53) { // Got a DNS response over TCP, maybe triggered by our app, or maybe not log_debug("[TCP] Got a DNS response from %s:%d to %s:%d.", sip, sport, dip, dport); // parse the DNS response to get the first qname const unsigned char *dns_payload = packet->payload + 2; struct mydnshdr *dnshdr = (struct mydnshdr*)dns_payload; unsigned short txn_id = htons(dnshdr->txn_id); int qdcount = ntohs(dnshdr->questions); char qname[MAX_QNAME_LEN]; if (qdcount > 0) { //log_debug("Questions: %d", qdcount); unsigned char *ptr = (unsigned char *)(dnshdr + 1); { struct mydnsquery query; int j = 0, l; while (1) { for (l = *ptr++; l != 0; l--) { query.qname[j++] = *ptr++; if (j >= MAX_QNAME_LEN) { while (*ptr != 0) ptr++; break; } } if (*ptr == 0) { query.qname[j] = 0; ptr++; break; } query.qname[j++] = '.'; } query.qtype = (ptr[0] << 8) + ptr[1]; query.qclass = (ptr[2] << 8) + ptr[3]; log_debug("DNS Query: %s %d %d", query.qname, query.qtype, query.qclass); // use the first query to calc hash qname[0] = 0; strncat(qname, query.qname, MAX_QNAME_LEN - 1); } // Tell the caching thread to process the dns udp response // use DNS transaction ID and first query name as unique ID // transaction ID alone may cause collision process_dns_tcp_response(txn_id, qname, &fourtp, tcphdr->th_seq, iphdr->ttl, packet->payload, packet->payload_len); } } else if (dport == opt_vpn_port) { // outgoing packet int sid = get_sid(&fourtp); if (sid >= 0 && g_strats[sid].process_request) { ret = g_strats[sid].process_request(packet); if (ret) { if (opt_inject_syn_and_syn_ack_with_one_ttl == 1) send_one_ttl_SYN(sip, sport, dip, dport, tcphdr->th_seq); else if (opt_inject_syn_and_syn_ack_with_one_ttl == 2) send_one_ttl_SYN_and_SYN_ACK(sip, sport, dip, dport, tcphdr->th_seq, tcphdr->th_ack); } } } else if (sport == opt_vpn_port) { // incomine packet } else if (dport == opt_tor_port) { // outgoing packet int sid = get_sid(&fourtp); if (sid >= 0 && g_strats[sid].process_request) { ret = g_strats[sid].process_request(packet); if (ret) { if (opt_inject_syn_and_syn_ack_with_one_ttl == 1) send_one_ttl_SYN(sip, sport, dip, dport, tcphdr->th_seq); else if (opt_inject_syn_and_syn_ack_with_one_ttl == 2) send_one_ttl_SYN_and_SYN_ACK(sip, sport, dip, dport, tcphdr->th_seq, tcphdr->th_ack); } } } else if (sport == opt_tor_port) { // incomine packet } else { // TODO: for all other protocols. This branch is a piece of temporary code, should be re-write. if (inout == 0) { // incoming packet log_debug("this is an incoming packet."); } else { // outgoing packet log_debug("this is an outgoing packet."); int sid = get_sid(&fourtp); if (sid >= 0 && g_strats[sid].process_request) { ret = g_strats[sid].process_request(packet); if (ret) { if (opt_inject_syn_and_syn_ack_with_one_ttl == 1) send_one_ttl_SYN(sip, sport, dip, dport, tcphdr->th_seq); else if (opt_inject_syn_and_syn_ack_with_one_ttl == 2) send_one_ttl_SYN_and_SYN_ACK(sip, sport, dip, dport, tcphdr->th_seq, tcphdr->th_ack); } } } } } else if (tcphdr->th_flags & TCP_RST) { // Got an incoming RST log_debug("[TCP] Got an incoming RST from %s:%d to %s:%d.", sip, sport, dip, dport); process_incoming_RST(packet); } return ret; }