void start_curl() { state = kDownloading; curl = curl_easy_init(); //assert(direct_ip.size()); std::string actual_url = redirect_url.size() ? redirect_url:url; char buf[1024]; sprintf(buf,"%s://%s%s%s", extract_proto(actual_url).c_str(), direct_ip.c_str(), extract_port(actual_url).c_str(), extract_path(actual_url).c_str()); curl_easy_setopt(curl, CURLOPT_URL, buf); sprintf(buf,"Host: %s%s",extract_host(actual_url).c_str(),extract_port(actual_url).c_str()); headers = curl_slist_append(headers,buf); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, Request::GotData); curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)this); curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-airplay-agent/1.0"); curl_easy_setopt(curl,CURLOPT_CONNECTTIMEOUT, 15); curl_easy_setopt(curl,CURLOPT_TIMEOUT, 30); curl_easy_setopt(curl,CURLOPT_NOPROGRESS, 0); curl_easy_setopt(curl,CURLOPT_FOLLOWLOCATION, 0); curl_easy_setopt(curl,CURLOPT_HEADERFUNCTION, Request::GotHeaderStatic); curl_easy_setopt(curl,CURLOPT_HEADERDATA, this); curl_easy_setopt(curl,CURLOPT_PROGRESSFUNCTION, Request::GotProgressStatic); curl_easy_setopt(curl,CURLOPT_PROGRESSDATA, (void *)this); //curl_easy_setopt(curl,CURLOPT_VERBOSE,1); if( curlsh ) curl_easy_setopt(curl,CURLOPT_SHARE,curlsh); if( curlm ) curl_multi_add_handle(curlm, curl); }
void load_database_contexts(Context_Map* context_map) { int prefix_mask {}; std::ifstream buf; buf.open(DBCONFIG_FILE); assert(buf.is_open()); std::string line {}; while (!buf.eof()) { getline(buf,line); if (ignore_line(line)) continue; else if (str_contains(line,'@')) { int port {}; std::string host {}; int db_num {}; // Complete at 00000111 (7) // One bit is set each time one of the above is found. // This allows for any number of newlines or comments. uint8_t completion {}; Prefix p {match_prefix(prefix_mask, line)}; while ((completion != 7) && !buf.eof()) { getline(buf,line); if (ignore_line(line)) continue; else if (str_contains(line,"port")) { port = extract_integer(line); completion |= 1; } else if (str_contains(line, "number")) { db_num = extract_integer(line); completion |= 2; } else if (str_contains(line, "host")) { host = extract_host(line); completion |= 4; } } assert(completion==7); Redis::Context* c = new Redis::Context(); c->port = port; c->host = host; c->db_num = db_num; context_map->set(p,c); assert(context_map->get(p)); } } buf.close(); assert(prefix_mask >= max_prefix_mask); assert(context_map); }
int dash_eval(char *line, char *std_input, char *origin) { if (line == NULL) return 1; int num_tokens; char **tokens = str_split(line, " ", &num_tokens); char *token; int i; int remote_pipe_pos = -1; for (i = 0; i < num_tokens; i++) { if (strcmp(tokens[i], REMOTE_PIPE) == 0) { remote_pipe_pos = i; break; } } if (remote_pipe_pos == -1) // No remote pipes { char *msg_data = dash_exec_scmd(tokens, remote_pipe_pos + 1, num_tokens, std_input); if (std_input == NULL) { printf("%s", msg_data); return 1; } else { // Send to origin char *fio_msg = dashp_fio(msg_data); send_to_host(fio_msg, origin); return 1; } } else // Remote pipe at remote_pipe_pos { char *subcommand = join_strings(tokens, " ", remote_pipe_pos+1, num_tokens); char *remotehost = extract_host(subcommand); char *maincommand = join_strings(tokens, " ", 0, remote_pipe_pos); char *msg_data = dash_exec_scmd(tokens, 0, remote_pipe_pos, std_input); char *send_msg; if (std_input == NULL) { // TODO: MAKE IP ADDRESS FUNCTION WORK! char *fin_remote_host = (char *) malloc (strlen(remotehost) + 1); strcat(fin_remote_host, remotehost); strcat(fin_remote_host, ":"); remove_substring(subcommand, fin_remote_host); free (fin_remote_host); subcommand[strlen(subcommand)-1] = '\0'; send_msg = dashp_pip(msg_data, "127.0.0.1", subcommand); } else { send_msg = dashp_pip(msg_data, origin, subcommand); } send_to_host(send_msg, remotehost); printf("Sent"); return 2; } }
void start_resolve() { if( ares ) { ares_destroy(ares); ares = 0; } state = kResolving; std::string actual_url = redirect_url.size() ? redirect_url:url; std::string host = extract_host(actual_url); std::string res = dns_cache->get_ent(host); if( !res.size() ) { ares_init(&ares); ares_gethostbyname(ares,host.c_str(),AF_INET,Request::GotResolveStatic,this); } else { char buf[1024]; sprintf(buf,"%d.%d.%d.%d",res[0],res[1],res[2],res[3]); direct_ip = buf; state = kStartDownload; } }
void GotResolve(int status, int timeouts, struct hostent *hostent) { switch(status) { case ARES_SUCCESS: { char buf[1024]; sprintf(buf,"%d.%d.%d.%d",hostent->h_addr[0],hostent->h_addr[1],hostent->h_addr[2],hostent->h_addr[3]); direct_ip = buf; state = kStartDownload; std::string actual_url = redirect_url.size() ? redirect_url:url; dns_cache->add_ent(extract_host(actual_url),hostent); } break; case ARES_EDESTRUCTION: break; case ARES_ECANCELLED: finish_error(status,"ARES_ECANCELLED"); break; case ARES_ETIMEOUT: finish_error(status,"ARES_ETIMEOUT"); break; case ARES_ENOTIMP: finish_error(status,"ARES_ENOTIMP"); break; case ARES_EBADNAME: finish_error(status,"ARES_EBADNAME"); break; case ARES_ENOTFOUND: finish_error(status,"ARES_ENOTFOUND"); break; case ARES_ENOMEM: finish_error(status,"ARES_ENOMEM"); break; default: finish_error(status,"ARES - UNKNOWN!"); break; } }
/* 处理客户端的连接 */ void handle_client(int client_sock, struct sockaddr_in client_addr) { int is_http_tunnel = 0; if(strlen(remote_host) == 0) /* 未指定远端主机名称从http 请求 HOST 字段中获取 */ { #ifdef DEBUG LOG(" ============ handle new client ============\n"); LOG(">>>Header:%s\n",header_buffer); #endif if(read_header(client_sock,header_buffer) < 0) { LOG("Read Http header failed\n"); return; } else { char * p = strstr(header_buffer,"CONNECT"); /* 判断是否是http 隧道请求 */ if(p) { LOG("receive CONNECT request\n"); is_http_tunnel = 1; } if(strstr(header_buffer,"GET /mproxy") >0 ) { LOG("====== hand mproxy info request ===="); //返回mproxy的运行基本信息 hand_mproxy_info_req(client_sock,header_buffer); return; } if(extract_host(header_buffer) < 0) { LOG("Cannot extract host field,bad http protrotol"); return; } LOG("Host:%s port: %d io_flag:%d\n",remote_host,remote_port,io_flag); } } if ((remote_sock = create_connection()) < 0) { LOG("Cannot connect to host [%s:%d]\n",remote_host,remote_port); return; } if (fork() == 0) { // 创建子进程用于从客户端转发数据到远端socket接口 if(strlen(header_buffer) > 0 && !is_http_tunnel) { forward_header(remote_sock); //普通的http请求先转发header } forward_data(client_sock, remote_sock); exit(0); } if (fork() == 0) { // 创建子进程用于转发从远端socket接口过来的数据到客户端 if(io_flag == W_S_ENC) { io_flag = R_C_DEC; //发送请求给服务端进行编码,读取服务端的响应则进行解码 } else if (io_flag == R_C_DEC) { io_flag = W_S_ENC; //接收客户端请求进行解码,那么响应客户端请求需要编码 } if(is_http_tunnel) { send_tunnel_ok(client_sock); } forward_data(remote_sock, client_sock); exit(0); } close(remote_sock); close(client_sock); }