std::vector<double> AnalizeFunction::MinFunc(double begin, double end) { if (end <= begin) throw std::invalid_argument("Error in MinFunc: end <= begin!\n"); double step = 1; double min = func_name(begin); std::vector<double> result; result.push_back(begin); // for (double x = begin; x <= end; x += step) { double next = func_name(x); if (min > next) { result.clear(); min = next; result.push_back(x); } else if (min == next) result.push_back(x); } return result; }
const SpObject *SpVM::eval(const SpExpr *expr, SpEnv *env) { // check whether this expression is an atom or a function call if (expr->head()->type() == TOKEN_FUNCTION_CALL) { // this is a function call expression std::string func_name(expr->head()->value()); // we find the function associated with this name in the given environment const SpObject *obj = resolve(func_name, env); if (obj == NULL || obj->type() != T_FUNCTION) RUNTIME_ERROR_F("'%s' is not a function", func_name.c_str()); // now call the function return call_function(func_name, static_cast<const SpFunction *>(obj->self()), expr, env); } else { // evaluate this atom std::string val = expr->head()->value(); switch (expr->head()->type()) { case TOKEN_NAME: { const SpObject *obj = resolve(val, env); if (obj == NULL) RUNTIME_ERROR_F("Undeclared variable '%s'", val.c_str()); return obj->shallow_copy(); } case TOKEN_NUMERIC: return new SpIntValue(atoi(val.c_str())); case TOKEN_CLOSURE: // the closure expression is stored in the first argument of the // object expression return new SpRefObject(new SpClosure(ArgList(), NULL, *expr->cbegin())); default: RUNTIME_ERROR("Unsupported operation"); } } }
bool Portfolio::readyForRun() { string func_name(" [Portfolio::readyForRun]"); if (!m_se) { HKU_WARN("m_se is null!" << func_name); return false; } if (!m_tm) { HKU_WARN("m_tm is null!" << func_name); return false; } if (!m_af) { HKU_WARN("m_am is null!" << func_name); return false; } reset(); //将影子账户指定给资产分配器 m_tm_shadow = m_tm->clone(); m_af->setTM(m_tm_shadow); return true; }
/** * Sends a pending aggregate message for a given group and message */ void send_pending(struct pr_group_list_t *group, int pendidx) { switch (group->pending[pendidx].msg) { case REGISTER: send_register(group, pendidx); break; case FILEINFO_ACK: send_fileinfo_ack(group, pendidx); break; case STATUS: send_status(group, pendidx); break; case COMPLETE: send_complete(group, pendidx); break; default: glog1(group, "Tried to send pending on invalid type %s", func_name(group->pending[pendidx].msg)); return; } if ((group->pending[pendidx].count <= 0) || (group->pending[pendidx].msg == STATUS)) { // Finish the cleanup we started in load_pending // Always do this for a STATUS, since we don't have a pending list free(group->pending[pendidx].naklist); memset(&group->pending[pendidx], 0, sizeof(struct pr_pending_info_t)); } }
/** * Sends a pending aggregate message for a given group and message */ void send_pending(int listidx, int pendidx) { switch (group_list[listidx].pending[pendidx].msg) { case REGISTER: send_register(listidx, pendidx); break; case INFO_ACK: send_info_ack(listidx, pendidx, FILEINFO); break; case STATUS: send_status(listidx, pendidx); break; case COMPLETE: send_complete(listidx, pendidx); break; default: log(group_list[listidx].group_id, 0, "Tried to send pending on " "invalid type %s", func_name(group_list[listidx].pending[pendidx].msg)); return; } if (group_list[listidx].pending[pendidx].count <= 0) { // Finish the cleanup we started in load_pending free(group_list[listidx].pending[pendidx].naklist); memset(&group_list[listidx].pending[pendidx], 0, sizeof(struct pr_pending_info_t)); } }
// Dump function name void CallNode::dump(ostream& s) const { s << func_name(); if (VSEFlags::include_list_info) s << *_arg; else if (_arg->isArgNode()) s << "(" << *_arg << "...)"; else s << *_arg; }
bool MySQLKDataDriver::_init() { string func_name(" [MySQLKDataDriver::MySQLKDataDriver]"); string default_host("127.0.0.1"); string default_usr("root"); string default_pwd(""); try { m_host = m_params.get<string>("host"); } catch(...) { m_host = default_host; HKU_WARN("Can't get mysql host! " << func_name); } try { m_port = m_params.get<int>("port"); } catch(...) { m_port = 3306; } try { m_usr = m_params.get<string>("usr"); } catch(...) { m_usr = default_usr; } try { m_pwd = m_params.get<string>("pwd"); } catch(...) { m_pwd = default_pwd; } shared_ptr<MYSQL> mysql(new MYSQL, MySQLCloser()); if (!mysql_init(mysql.get())) { HKU_ERROR(" Initial MySQL handle error!" << func_name); return false; } if (!mysql_real_connect(mysql.get(), m_host.c_str(), m_usr.c_str(), m_pwd.c_str(), NULL, m_port, NULL, 0) ) { HKU_ERROR(" Failed to connect to database!" << func_name); return false; } if (mysql_set_character_set(mysql.get(), "utf8")) { HKU_ERROR(" mysql_set_character_set error!" << func_name); return false; } m_mysql = mysql; return true; }
KRecord MySQLKDataDriver:: getKRecord(const string& market, const string& code, size_t pos, KQuery::KType kType) { string func_name(" [MySQLKDataDriver::getKRecord]"); KRecord result; if (!m_mysql) { HKU_ERROR("Null m_mysql!" << func_name); return result; } /*if (kType >= KQuery::INVALID_KTYPE ) { HKU_WARN("ktype(" << kType << ") is invalid" << func_name); return result; }*/ MYSQL_RES *mysql_result; MYSQL_ROW row; string table(_getTableName(market, code, kType)); std::stringstream buf (std::stringstream::out); buf << "select date, open, high, low, close, amount, count from " << table << " order by date limit " << pos << ", 1"; if (!_query(buf.str())) { HKU_ERROR("mysql_query error! " << func_name); return result; } mysql_result = mysql_store_result(m_mysql.get()); if (!mysql_result) { HKU_ERROR("mysql_store_result error!" << func_name); return result; } while ((row = mysql_fetch_row(mysql_result))) { try { hku_uint64 d = boost::lexical_cast<hku_uint64>(row[0]); result.datetime = Datetime(d); result.openPrice = boost::lexical_cast<price_t>(row[1]); result.highPrice = boost::lexical_cast<price_t>(row[2]); result.lowPrice = boost::lexical_cast<price_t>(row[3]); result.closePrice = boost::lexical_cast<price_t>(row[4]); result.transAmount = boost::lexical_cast<price_t>(row[5]); result.transCount = boost::lexical_cast<price_t>(row[6]); } catch (...) { HKU_INFO("Error get record " << pos << " " << table << func_name); result = Null<KRecord>(); } } mysql_free_result(mysql_result); return result; }
size_t MySQLKDataDriver:: getCount(const string& market, const string& code, KQuery::KType kType) { string func_name(" [MySQLKDataDriver::getCount]"); size_t result = 0; if (!m_mysql) { HKU_ERROR("Null m_mysql!" << func_name); return result; } /*if (kType >= KQuery::INVALID_KTYPE ) { HKU_WARN("ktype(" << kType << ") is invalid" << func_name); return result; }*/ MYSQL_RES *mysql_result; MYSQL_ROW row; string table(_getTableName(market, code, kType)); std::stringstream buf (std::stringstream::out); buf << "select count(1) from " << table; if (!_query(buf.str())) { HKU_ERROR("mysql_query error! " << func_name); return result; } mysql_result = mysql_store_result(m_mysql.get()); if (!mysql_result) { HKU_ERROR("mysql_store_result error!" << func_name); return result; } while ((row = mysql_fetch_row(mysql_result))) { try { result = boost::lexical_cast<size_t>(row[0]); } catch (...) { HKU_INFO("Error get record count of" << table << func_name); result = 0; } } mysql_free_result(mysql_result); return result; }
/*! * @brief Set size and thickness parameters if SIZE command is specified * @param cmd Command * @param loc Position of the first character to be checked * @return SET_SCALE_AND_THICKNESS if size and thickness parameter is set, 0 if not SIZE command */ int CommentGenerator::checkSIZE(std::string &cmd, std::string::size_type &loc){ int res; std::vector<double> value_tmp; std::string func_name("SIZE("); res = getFunctionArgs(cmd, loc, func_name, 1, value_tmp); if(res>0){ if(value_tmp[0]<=0){ std::cerr << "Error in CommentGenerator::checkSIZE(): invalid command - SIZE values must be >0" << std::endl; return -4; //error } thick = (value_tmp[0]/scale)*thick; scale = value_tmp[0]; return SET_SCALE_AND_THICKNESS; //found } return res; }
//std::pair<std::string, std::string> matchFunctionDef(const std::string& input) std::smatch matchFunctionDef(const std::string& input) { std::smatch func_def_match; std::regex regex_def("(virtual|friend)?\\s*([[:alpha:]][[:alpha:][:digit:]_]*)\\s+([[:alpha:]][[:alpha:][:digit:]_]*)\\s*\\(\\s*(((.*)\\s*([[:alpha:]][[:alpha:]]*)\\s*[,]\\s*)*(.*)\\s*([[:alpha:]][[:alpha:]]*)*)\\s*\\);"); if(std::regex_search(input,func_def_match,regex_def)) { std::string func_name(func_def_match.str(3)); //Extracting function name std::string func_param(func_def_match.str(4)); //Extracting function params //return std::pair<std::string, std::string>(func_name,func_param); //return func_def_match; } #if 0 else { //return std::pair<std::string, std::string>("",""); return std::string(""); } #endif return func_def_match; }
void testmain(void) { print("function"); expect(77, t1()); t2(79); t3(1, 2, 3, 4, 5, 6); t4(); t5(); expect(3, t6()); expect(12, t7(3, 4)); t8(23); t9(); expect(7, t10(3, 4.0)); func_ptr_call(); func_name(); empty(); empty2(); test_bool(); test_struct(); }
/** * Sets the timeout time for a given group list member */ void set_timeout(struct pr_group_list_t *group, int pending_reset, int rescale) { int pending, i; if (group->phase == PR_PHASE_READY) { if (!rescale) { gettimeofday(&group->start_phase_timeout_time, NULL); } group->phase_timeout_time = group->start_phase_timeout_time; add_timeval_d(&group->phase_timeout_time, 2 * group->grtt); } glog5(group, "set timeout: pending_reset=%d", pending_reset); for (pending = 0, i = 0; (i < MAX_PEND) && !pending; i++) { if (group->pending[i].msg != 0) { glog5(group, "set timeout: found pending %s", func_name(group->pending[i].msg)); pending = group->pending[i].msg; } } if (pending) { if (pending_reset) { if (!rescale) { gettimeofday(&group->start_timeout_time, NULL); } group->timeout_time = group->start_timeout_time; add_timeval_d(&group->timeout_time, 1 * group->grtt); } } else { if (!rescale) { gettimeofday(&group->start_timeout_time, NULL); } group->timeout_time = group->start_timeout_time; if (group->robust * group->grtt < 1.0) { add_timeval_d(&group->timeout_time, 1.0); } else { add_timeval_d(&group->timeout_time, group->robust * group->grtt); } } }
unique_ptr<builder_i> recursive_parser::create_builder(builder_factory_i& factory) { unique_ptr<builder_i> builder; if(name_.first == name_.second) { if(arguments_.size() == 1) builder = arguments_[0]->create_builder(factory); else throw parse_error("only one expression is expected!"); } else { string func_name(name_.first, name_.second); builder = factory.create_function(func_name); for(auto& arg : arguments_) { builder->merge(arg->create_builder(factory)); } } return move(builder); }
bool MySQLKDataDriver::_query(const string& sql_str) { string func_name(" [MySQLKDataDriver::query]"); int res = mysql_query(m_mysql.get(), sql_str.c_str()); if (!res) { return true; } //重新连接数据库 HKU_INFO("MySQL connect invalid, will retry connect!" << func_name); m_mysql = NULL; shared_ptr<MYSQL> mysql(new MYSQL, MySQLCloser()); if (!mysql_init(mysql.get())) { HKU_ERROR(" Initial MySQL handle error!" << func_name); return false; } if (!mysql_real_connect(mysql.get(), m_host.c_str(), m_usr.c_str(), m_pwd.c_str(), NULL, m_port, NULL, 0) ) { HKU_ERROR(" Failed to connect to database!" << func_name); return false; } if (mysql_set_character_set(mysql.get(), "utf8")) { HKU_ERROR(" mysql_set_character_set error!" << func_name); return false; } m_mysql = mysql; res = mysql_query(m_mysql.get(), sql_str.c_str()); if(!res) { return true; } HKU_ERROR("mysql_query error! error no: " << res << " " << sql_str << func_name); return false; }
void testmain() { print("function"); expect(77, t1()); t2(79); t3(1, 2, 3, 4, 5, 6); t4(); t5(); expect(3, t6()); expect(12, t7(3, 4)); expect(77, (1 ? t1 : t6)()); expect(3, (0 ? t1 : t6)()); t8(23); t9(); expect(7, t10(3, 4.0)); func_ptr_call(); func_name(); local_static(); empty(); empty2(); test_bool(); test_struct(); test_funcdesg(); }
/*! * @brief Set color parameter if RGB command is specified * @param cmd Command * @param loc Position of the first character to be checked * @return SET_COLOR if color parameter is set, 0 if not RGB command */ int CommentGenerator::checkRGB(std::string &cmd, std::string::size_type &loc){ int res; std::vector<double> color_tmp; std::string func_name("RGB("); res = getFunctionArgs(cmd, loc, func_name, 3, color_tmp); if(res>0){ for(int i=0;i<3;i++){ if(color_tmp[i]<0||color_tmp[i]>255){ std::cerr << "Error in CommentGenerator::checkRGB(): invalid command - RGB values must be [0, 255]" << std::endl; return -4; //error } if(std::floor(color_tmp[i]) != std::ceil(color_tmp[i])){ std::cerr << "Error in CommentGenerator::checkRGB(): invalid command - expected integer value" << std::endl; return -4; //error } } color.val[0] = color_tmp[2]; color.val[1] = color_tmp[1]; color.val[2] = color_tmp[0]; return SET_COLOR; //found } return res; }
//std::pair<std::string, std::string> matchFunctionCall(const std::string& input) std::smatch matchFunctionCall(const std::string& input) { const char *for_const ="for("; if(input.rfind(for_const,0)!=0) { std::smatch func_call_match; std::regex regex_call("([[:alpha:]][[:alpha:][:digit:]_]*)\\(\\s*(([[:alpha:]][[:alpha:][:digit:]_]*\\s*:[^:]*\\s*)\\s*(,\\s*[[:alpha:]][[:alpha:][:digit:]_]*\\s*:[^:]*\\s*)*)\\)\\s*"); if(std::regex_search(input,func_call_match,regex_call)) { std::string func_name(func_call_match.str(1)); //Extracting function name std::string func_param(func_call_match.str(2)); //Extracting function params //return std::pair<std::string, std::string>(func_name,func_param); //return func_call_match.str(0); } #if 0 else { return std::string(""); //return std::pair<std::string, std::string>("",""); } #endif return func_call_match; } }
SgFunctionDeclaration * CudaOutliner::generateFunction ( SgBasicBlock* s, const string& func_name_str, ASTtools::VarSymSet_t& syms, MintHostSymToDevInitMap_t hostToDevVars, const ASTtools::VarSymSet_t& pdSyms, const ASTtools::VarSymSet_t& psyms, SgScopeStatement* scope) { //Create a function named 'func_name_str', with a parameter list from 'syms' //pdSyms specifies symbols which must use pointer dereferencing if replaced during outlining, //only used when -rose:outline:temp_variable is used //psyms are the symbols for OpenMP private variables, or dead variables (not live-in, not live-out) ROSE_ASSERT ( s && scope); ROSE_ASSERT(isSgGlobal(scope)); // step 1: perform necessary liveness and side effect analysis, if requested. // --------------------------------------------------------- std::set< SgInitializedName *> liveIns, liveOuts; // Collect read-only variables of the outlining target std::set<SgInitializedName*> readOnlyVars; if (Outliner::temp_variable||Outliner::enable_classic) { SgStatement* firstStmt = (s->get_statements())[0]; if (isSgForStatement(firstStmt)&& Outliner::enable_liveness) { LivenessAnalysis * liv = SageInterface::call_liveness_analysis (SageInterface::getProject()); SageInterface::getLiveVariables(liv, isSgForStatement(firstStmt), liveIns, liveOuts); } SageInterface::collectReadOnlyVariables(s,readOnlyVars); if (0)//Outliner::enable_debug) { cout<<" INFO:Mint: CudaOutliner::generateFunction()---Found "<<readOnlyVars.size()<<" read only variables..:"; for (std::set<SgInitializedName*>::const_iterator iter = readOnlyVars.begin(); iter!=readOnlyVars.end(); iter++) cout<<" "<<(*iter)->get_name().getString()<<" "; cout<<endl; cout<<"CudaOutliner::generateFunction() -----Found "<<liveOuts.size()<<" live out variables..:"; for (std::set<SgInitializedName*>::const_iterator iter = liveOuts.begin(); iter!=liveOuts.end(); iter++) cout<<" "<<(*iter)->get_name().getString()<<" "; cout<<endl; } } //step 2. Create function skeleton, 'func'. // ----------------------------------------- SgName func_name (func_name_str); SgFunctionParameterList *parameterList = buildFunctionParameterList(); SgType* func_Type = SgTypeVoid::createType (); SgFunctionDeclaration* func = createFuncSkeleton (func_name, func_Type ,parameterList, scope); //adds __global__ keyword func->get_functionModifier().setCudaKernel(); ROSE_ASSERT (func); // Liao, 4/15/2009 , enforce C-bindings for C++ outlined code // enable C code to call this outlined function // Only apply to C++ , pure C has trouble in recognizing extern "C" // Another way is to attach the function with preprocessing info: // #if __cplusplus // extern "C" // #endif // We don't choose it since the language linkage information is not explicit in AST if ( SageInterface::is_Cxx_language() || is_mixed_C_and_Cxx_language() \ || is_mixed_Fortran_and_Cxx_language() || is_mixed_Fortran_and_C_and_Cxx_language() ) { // Make function 'extern "C"' func->get_declarationModifier().get_storageModifier().setExtern(); func->set_linkage ("C"); } //step 3. Create the function body // ----------------------------------------- // Generate the function body by deep-copying 's'. SgBasicBlock* func_body = func->get_definition()->get_body(); ROSE_ASSERT (func_body != NULL); // This does a copy of the statements in "s" to the function body of the outlined function. ROSE_ASSERT(func_body->get_statements().empty() == true); // This calls AST copy on each statement in the SgBasicBlock, but not on the block, so the // symbol table is setup by AST copy mechanism and it is setup properly SageInterface::moveStatementsBetweenBlocks (s, func_body); if (Outliner::useNewFile) ASTtools::setSourcePositionAtRootAndAllChildrenAsTransformation(func_body); //step 4: variable handling, including: // ----------------------------------------- // create parameters of the outlined functions // add statements to unwrap the parameters if wrapping is requested // add repacking statements if necessary // replace variables to access to parameters, directly or indirectly // do not wrap parameters Outliner::enable_classic = true; functionParameterHandling(syms, hostToDevVars, pdSyms, psyms, readOnlyVars, liveOuts, func); ROSE_ASSERT (func != NULL); // Retest this... // Copied the similar fix from the rose outliner // Liao 2/6/2013. It is essential to rebuild function type after the parameter list is finalized. // The original function type was build using empty parameter list. SgType* stale_func_type = func->get_type(); func->set_type(buildFunctionType(func->get_type()->get_return_type(), buildFunctionParameterTypeList(func->get_parameterList()))); SgFunctionDeclaration* non_def_func = isSgFunctionDeclaration(func->get_firstNondefiningDeclaration ()) ; ROSE_ASSERT (non_def_func != NULL); ROSE_ASSERT (stale_func_type == non_def_func->get_type()); non_def_func->set_type(func->get_type()); ROSE_ASSERT(func->get_definition()->get_body()->get_parent() == func->get_definition()); ROSE_ASSERT(scope->lookup_function_symbol(func->get_name())); return func; }
/** * Check an announce phase message and pass to appropriate message handler, * decrypting first if necessary * Returns 1 on success, 0 on error */ int handle_announce_phase(const unsigned char *packet, unsigned char *decrypted, const struct sockaddr_in *receiver, struct finfo_t *finfo, int announce, int open, int regconf) { struct uftp_h *header; const unsigned char *message; int hostidx; unsigned decryptlen, meslen; uint8_t *func; struct in_addr srcaddr; header = (struct uftp_h *)packet; hostidx = find_client(header->srcaddr); if (header->srcaddr == 0) { srcaddr = receiver->sin_addr; } else { srcaddr.s_addr = header->srcaddr; } if ((keytype != KEY_NONE) && (header->func == ENCRYPTED)) { if (hostidx == -1) { log(0, 0, "Got encrypted packet from unknown receiver %s", inet_ntoa(srcaddr)); return 0; } if (!validate_and_decrypt(packet, &decrypted, &decryptlen, mtu, keytype, groupkey, groupsalt, ivlen, hashtype, grouphmackey, hmaclen, sigtype, destlist[hostidx].encinfo->pubkey, destlist[hostidx].encinfo->pubkeylen)) { log1(0, 0, "Rejecting message from %s: decrypt/validate failed", destlist[hostidx].name); return 0; } func = (uint8_t *)decrypted; message = decrypted; meslen = decryptlen; } else { if ((keytype != KEY_NONE) && (header->func == INFO_ACK)) { log1(0, 0, "Rejecting %s message from %s: not encrypted", func_name(header->func), inet_ntoa(srcaddr)); return 0; } func = (uint8_t *)&header->func; message = packet + sizeof(struct uftp_h); meslen = ntohs(header->blsize); } if (*func == ABORT) { handle_abort(message, meslen, hostidx, finfo, &srcaddr); return 1; } if (hostidx == -1) { if (open) { if (*func == REGISTER) { handle_open_register(message, meslen, finfo, receiver, &srcaddr, regconf); } else if (*func == CLIENT_KEY) { handle_open_clientkey(message, meslen, finfo, receiver, &srcaddr); } else { log1(0, 0, "Invalid function: expected " "REGISTER or CLIENT_KEY, got %s", func_name(*func)); } } else { log1(0, 0, "Host %s not in host list", inet_ntoa(srcaddr)); send_abort(finfo, "Not in host list", receiver, &srcaddr, 0, 0); } } else { switch (destlist[hostidx].status) { case DEST_MUTE: if (*func == REGISTER) { handle_register(message, meslen, finfo, receiver, &srcaddr, hostidx, regconf, open); } else if (*func == CLIENT_KEY) { handle_clientkey(message, meslen, finfo, receiver, &srcaddr, hostidx); } else { log1(0, 0, "Invalid function: expected " "REGISTER or CLIENT_KEY, got %s", func_name(*func)); } break; case DEST_REGISTERED: if (*func == INFO_ACK) { handle_info_ack(message, meslen, finfo, receiver, &srcaddr, hostidx, announce); } else if (*func == REGISTER) { handle_register(message, meslen, finfo, receiver, &srcaddr, hostidx, regconf, open); } else if (*func == CLIENT_KEY) { log(0, 0, "Received CLIENT_KEY+ from %s", destlist[hostidx].name); } else if (!announce && (*func == COMPLETE)) { handle_complete(message, meslen, finfo, hostidx); } else { log1(0, 0, "Received invalid message %s from %s", func_name(*func), destlist[hostidx].name); } break; case DEST_ACTIVE: if (*func == REGISTER) { handle_register(message, meslen, finfo, receiver, &srcaddr, hostidx, regconf, open); } else if (*func == CLIENT_KEY) { log(0, 0, "Received CLIENT_KEY+ from %s", destlist[hostidx].name); } else if (*func == INFO_ACK) { finfo->deststate[hostidx].conf_sent = 0; handle_info_ack(message, meslen, finfo, receiver, &srcaddr, hostidx, announce); } else if (!announce && (*func == COMPLETE)) { handle_complete(message, meslen, finfo, hostidx); } else { log1(0, 0, "Received invalid message %s from %s", func_name(*func), destlist[hostidx].name); } break; default: log1(0, 0, "Received invalid message %s from %s", func_name(*func), destlist[hostidx].name); break; } } return 1; }
/** * Puts the given message on the pending message list. If it doesn't match * any pending message and there are no open slots, first send what's pending. * If the pending list is full after adding the given message, then send. */ void check_pending(int listidx, int hostidx, const unsigned char *message) { struct infoack_h *infoack; struct status_h *status; struct complete_h *complete; const uint8_t *func; struct pr_pending_info_t *pending; int match, pendidx; func = message; infoack = (struct infoack_h *)message; status = (struct status_h *)message; complete = (struct complete_h *)message; for (pendidx = 0; pendidx < MAX_PEND; pendidx++) { pending = &group_list[listidx].pending[pendidx]; if (group_list[listidx].pending[pendidx].msg == 0) { match = 1; break; } match = (*func == pending->msg); switch (*func) { case REGISTER: // REGISTER always matches itself break; case INFO_ACK: // Only in response to FILEINFO. // Responses to KEYINFO are not forwarded. match = match && (ntohs(infoack->file_id) == pending->file_id); break; case STATUS: match = match && ((ntohs(status->file_id) == pending->file_id) && (status->pass == pending->pass) && (ntohs(status->section) == pending->section)); break; case COMPLETE: match = match && ((ntohs(complete->file_id) == pending->file_id) && (complete->status == pending->comp_status)); break; default: log(group_list[listidx].group_id, 0, "Tried to check pending " "on invalid type %s", func_name(*func)); return; } if (match) { break; } } if (!match) { send_all_pending(listidx); pendidx = 0; pending = &group_list[listidx].pending[pendidx]; } pending->msg = *func; if (group_list[listidx].destinfo[hostidx].pending != pendidx) { group_list[listidx].destinfo[hostidx].pending = pendidx; pending->count++; } switch (*func) { case INFO_ACK: if (pending->count == 1) { pending->partial = 1; } pending->file_id = ntohs(infoack->file_id); pending->partial = pending->partial && ((infoack->flags & FLAG_PARTIAL) != 0); break; case STATUS: pending->file_id = ntohs(status->file_id); pending->pass = status->pass; pending->section = ntohs(status->section); pending->seq = group_list[listidx].last_seq; if (!pending->naklist) { pending->naklist = calloc(group_list[listidx].blocksize, 1); if (pending->naklist == NULL) { syserror(0, 0, "calloc failed!"); exit(1); } } if (ntohl(status->nak_count) != 0) { add_naks_to_pending(listidx, pendidx, message); } break; case COMPLETE: pending->file_id = ntohs(complete->file_id); pending->comp_status = complete->status; break; } if (pending->count == max_msg_dest(listidx, *func)) { send_pending(listidx, pendidx); } else { int total_pending, i; for (total_pending = 0, i = 0; i < MAX_PEND; i++) { total_pending += group_list[listidx].pending[i].count; } if (total_pending == 1) { set_timeout(listidx, 1); } } }
/** * Puts the given message on the pending message list. If it doesn't match * any pending message and there are no open slots, first send what's pending. * If the pending list is full after adding the given message, then send. */ void check_pending(struct pr_group_list_t *group, int hostidx, const unsigned char *message) { const struct fileinfoack_h *fileinfoack; const struct status_h *status; const struct complete_h *complete; const uint8_t *func; struct pr_pending_info_t *pending; int match, pendidx, hlen; func = message; fileinfoack = (const struct fileinfoack_h *)message; status = (const struct status_h *)message; complete = (const struct complete_h *)message; glog3(group, "check_timeout: looking for pending %s", func_name(*func)); for (pendidx = 0; pendidx < MAX_PEND; pendidx++) { pending = &group->pending[pendidx]; if (group->pending[pendidx].msg == 0) { glog3(group, "check_timeout: found empty slot %d", pendidx); match = 1; break; } match = (*func == pending->msg); switch (*func) { case REGISTER: // REGISTER always matches itself break; case FILEINFO_ACK: match = match && (ntohs(fileinfoack->file_id) == pending->file_id); break; case STATUS: match = match && ((ntohs(status->file_id) == pending->file_id) && (ntohs(status->section) == pending->section)); break; case COMPLETE: match = match && ((ntohs(complete->file_id) == pending->file_id) && (complete->status == pending->comp_status)); break; default: glog1(group, "Tried to check pending on invalid type %s", func_name(*func)); return; } if (match) { break; } } if (!match) { send_all_pending(group); pendidx = 0; pending = &group->pending[pendidx]; } glog3(group, "check_timeout: found match at slot %d", pendidx); pending->msg = *func; if (group->destinfo[hostidx].pending != pendidx) { group->destinfo[hostidx].pending = pendidx; pending->count++; } switch (*func) { case REGISTER: hlen = sizeof(struct register_h); if (pending->count == 1) { gettimeofday(&pending->rx_tstamp, NULL); pending->tstamp = group->destinfo[hostidx].regtime; glog3(group, "send time = %d.%06d", pending->tstamp.tv_sec, pending->tstamp.tv_usec); glog3(group, "rx time = %d.%06d", pending->rx_tstamp.tv_sec, pending->rx_tstamp.tv_usec); } break; case FILEINFO_ACK: hlen = sizeof(struct fileinfoack_h); if (pending->count == 1) { pending->partial = 1; gettimeofday(&pending->rx_tstamp, NULL); pending->tstamp.tv_sec = ntohl(fileinfoack->tstamp_sec); pending->tstamp.tv_usec = ntohl(fileinfoack->tstamp_usec); glog3(group, "send time = %d.%06d", pending->tstamp.tv_sec, pending->tstamp.tv_usec); glog3(group, "rx time = %d.%06d", pending->rx_tstamp.tv_sec, pending->rx_tstamp.tv_usec); } pending->file_id = ntohs(fileinfoack->file_id); pending->partial = pending->partial && ((fileinfoack->flags & FLAG_PARTIAL) != 0); break; case STATUS: hlen = sizeof(struct status_h); pending->file_id = ntohs(status->file_id); pending->section = ntohs(status->section); if (!pending->naklist) { pending->naklist = safe_calloc(group->blocksize, 1); } add_naks_to_pending(group, pendidx, message); break; case COMPLETE: hlen = sizeof(struct complete_h); pending->file_id = ntohs(complete->file_id); pending->comp_status = complete->status; break; } if ((*func != STATUS) && (pending->count == max_msg_dest(group, *func, hlen))) { send_pending(group, pendidx); } else { int total_pending, i; glog3(group, "check_timeout: getting pending count for %s", func_name(*func)); for (total_pending = 0, i = 0; i < MAX_PEND; i++) { glog3(group, "check_timeout: adding %d pending for %d", group->pending[i].count, i); total_pending += group->pending[i].count; } if (total_pending == 1) { set_timeout(group, 1, 0); } } }
// ...as tree void CallNode::_dumpTree(ostream& s) const { s << "\"" << func_name() << "\", "; _arg->dumpTree(s); }
/** * This is the main message reading loop. Messages are read, validated, * decrypted if necessary, then passed to the appropriate routine for handling. */ void mainloop() { struct uftp_h *header; struct uftp2_h *v2_header; unsigned char *buf, *decrypted, *message; unsigned int decryptlen, meslen, expectedlen; int packetlen, listidx, i; uint8_t version, *func; uint32_t v2func; struct sockaddr_in src; struct timeval *tv; const int bsize = 9000; // Roughly size of ethernet jumbo frame log0(0, 0, "%s", VERSIONSTR); for (i = 0; i < key_count; i++) { log1(0, 0, "Loaded key with fingerprint %s", print_key_fingerprint(privkey[i])); } buf = calloc(bsize, 1); decrypted = calloc(bsize, 1); if ((buf == NULL) || (decrypted == NULL)){ syserror(0, 0, "calloc failed!"); exit(1); } header = (struct uftp_h *)buf; v2_header = (struct uftp2_h *)buf; while (1) { tv = getrecenttimeout(); if (read_packet(listener, &src, buf, &packetlen, bsize, tv) <= 0) { continue; } if ((header->uftp_id == UFTP_VER_NUM) || (header->uftp_id == UFTP_3_0_VER)) { version = header->uftp_id; expectedlen = sizeof(struct uftp_h) + ntohs(header->blsize); listidx = find_file(ntohl(header->group_id)); } else if (ntohl(v2_header->uftp_id) == V2_UFTP_ID) { version = UFTP_V2_VER; expectedlen = V2_PACKETSIZE; listidx = find_file(ntohl(v2_header->tx_id)); v2func = ntohl(v2_header->func); } else { log(0, 0, "Invalid message from %s: not uftp packet " "or invalid version", inet_ntoa(src.sin_addr)); continue; } if (packetlen != expectedlen) { log(0, 0, "Invalid packet size from %s: got %d, expected %d", inet_ntoa(src.sin_addr), packetlen, expectedlen); continue; } if (((version == UFTP_VER_NUM) || (version == UFTP_3_0_VER)) && (header->func == ENCRYPTED) && (listidx != -1) && (group_list[listidx].keytype != KEY_NONE)) { if (group_list[listidx].phase == PHASE_REGISTERED) { log(ntohl(header->group_id), 0, "Got encrypted packet from %s " "but keys not established", inet_ntoa(src.sin_addr)); } if (!validate_and_decrypt(buf, &decrypted, &decryptlen, group_list[listidx].mtu, group_list[listidx].keytype, group_list[listidx].groupkey, group_list[listidx].groupsalt, group_list[listidx].ivlen, group_list[listidx].hashtype, group_list[listidx].grouphmackey, group_list[listidx].hmaclen, group_list[listidx].sigtype, group_list[listidx].serverkey, group_list[listidx].server_keylen)) { log(ntohl(header->group_id), 0, "Rejecting message from %s: " "decrypt/validate failed", inet_ntoa(src.sin_addr)); continue; } func = (uint8_t *)decrypted; message = decrypted; meslen = decryptlen; } else if ((version == UFTP_VER_NUM) || (version == UFTP_3_0_VER)) { if ((listidx != -1) && (group_list[listidx].keytype != KEY_NONE) && ((header->func == FILEINFO) || (header->func == FILESEG) || (header->func == DONE) || (header->func == DONE_CONF) || ((header->func == ABORT) && (group_list[listidx].phase != PHASE_REGISTERED)))) { log(0, 0, "Rejecting %s message from %s: not encrypted", func_name(header->func), inet_ntoa(src.sin_addr)); continue; } func = (uint8_t *)&header->func; message = buf + sizeof(struct uftp_h); meslen = ntohs(header->blsize); } else { // Version 2 message = buf; meslen = V2_PACKETSIZE; } if (((version == UFTP_VER_NUM) || (version == UFTP_3_0_VER)) && (header->func == PROXY_KEY)) { handle_proxy_key(&src, buf); continue; } if (((version == UFTP_VER_NUM) || (version == UFTP_3_0_VER)) && (header->func == HB_RESP)) { handle_hb_response(listener, &src, buf, hb_hosts, hbhost_count, noname, privkey[0]); continue; } if ((((version == UFTP_VER_NUM) || (version == UFTP_3_0_VER)) && (header->func == ANNOUNCE)) || ((version == UFTP_V2_VER) && (v2func == V2_ANNOUNCE))) { // Ignore any ANNOUNCE for a group we're already handling if (listidx == -1) { handle_announce(src, version, buf); } else if (group_list[listidx].phase == PHASE_MIDGROUP) { // Make sure we don't time out while waiting for other // clients to register with the server. set_timeout(listidx); } } else { if (listidx == -1) { // group / file ID not in list continue; } if (group_list[listidx].version != version) { log(group_list[listidx].group_id, group_list[listidx].file_id, "Version mismatch"); continue; } if ((((version == UFTP_VER_NUM) || (version == UFTP_3_0_VER)) && (*func == ABORT)) || ((version == UFTP_V2_VER) && (v2func == V2_ABORT))) { handle_abort(listidx, message, meslen); continue; } switch (group_list[listidx].phase) { case PHASE_REGISTERED: if (version == UFTP_V2_VER) { // This is repeated in one of the cases below, but it's // separated out anyway to keep the V2 stuff separate. handle_regconf(listidx, message, meslen); } else if (group_list[listidx].keytype != KEY_NONE) { if (*func == KEYINFO) { handle_keyinfo(listidx, buf); } else { log(group_list[listidx].group_id, group_list[listidx].file_id, "Expected KEYINFO, got %s", func_name(*func)); } } else if (group_list[listidx].keytype == KEY_NONE) { if (*func == REG_CONF) { handle_regconf(listidx, message, meslen); } else if (*func == FILEINFO) { handle_fileinfo(listidx, message, meslen); } else { log(group_list[listidx].group_id, group_list[listidx].file_id, "Expected REG_CONF, got %s", func_name(*func)); } } break; case PHASE_MIDGROUP: if (((version == UFTP_VER_NUM) || (version == UFTP_3_0_VER)) && (*func == FILEINFO)) { handle_fileinfo(listidx, message, meslen); } else if (((version == UFTP_VER_NUM) || (version == UFTP_3_0_VER)) && (*func == KEYINFO)) { handle_keyinfo(listidx, buf); } else if (((version == UFTP_V2_VER) && (v2func == V2_DONE)) || (((version == UFTP_VER_NUM) || (version == UFTP_3_0_VER)) && (*func == DONE))) { handle_done(listidx, message, meslen); } else { // Other clients may be still getting earlier files or // setting up, so silently ignore anything unexpected // and reset the timeout. set_timeout(listidx); } break; case PHASE_RECEIVING: if (((version == UFTP_VER_NUM) || (version == UFTP_3_0_VER)) && (*func == FILEINFO)) { handle_fileinfo(listidx, message, meslen); } else if (((version == UFTP_V2_VER) && (v2func == V2_FILESEG)) || (((version == UFTP_VER_NUM) || (version == UFTP_3_0_VER)) && (*func == FILESEG))) { handle_fileseg(listidx, message, meslen); } else if (((version == UFTP_V2_VER) && (v2func == V2_DONE)) || (((version == UFTP_VER_NUM) || (version == UFTP_3_0_VER)) && (*func == DONE))) { handle_done(listidx, message, meslen); } break; case PHASE_COMPLETE: if (((version == UFTP_V2_VER) && (v2func == V2_DONE_CONF)) || (((version == UFTP_VER_NUM) || (version == UFTP_3_0_VER)) && (*func == DONE_CONF))) { handle_done_conf(listidx, message, meslen); } break; } } } }
/** * This is the main message reading loop. Messages are read, validated, * decrypted if necessary, then passed to the appropriate routine for handling. */ void mainloop(void) { struct uftp_h *header; struct group_list_t *group; unsigned char *buf, *decrypted, *message; char rxname[INET6_ADDRSTRLEN]; unsigned int decryptlen, meslen; int packetlen, rval, i, ecn; uint8_t version, *func, tos; uint16_t txseq; union sockaddr_u src; struct timeval *tv, rxtime; double new_grtt; log2(0, 0, 0, "%s", VERSIONSTR); for (i = 0; i < key_count; i++) { if (privkey_type[i] == KEYBLOB_RSA) { log2(0, 0, 0, "Loaded %d bit RSA key with fingerprint %s", RSA_keylen(privkey[i].rsa) * 8, print_key_fingerprint(privkey[i], KEYBLOB_RSA)); } else { log2(0, 0, 0, "Loaded ECDSA key with curve %s and fingerprint %s", curve_name(get_EC_curve(privkey[i].ec)), print_key_fingerprint(privkey[i], KEYBLOB_EC)); } } buf = safe_calloc(MAXMTU, 1); decrypted = safe_calloc(MAXMTU, 1); header = (struct uftp_h *)buf; while (1) { tv = getrecenttimeout(); if (tv) { log5(0, 0, 0, "read timeout: %d.%06d", tv->tv_sec, tv->tv_usec); } if (read_packet(listener, &src, buf, &packetlen, MAXMTU, tv, &tos) <= 0) { continue; } gettimeofday(&rxtime, NULL); if ((rval = getnameinfo((struct sockaddr *)&src, family_len(src), rxname, sizeof(rxname), NULL, 0, NI_NUMERICHOST)) != 0) { log1(0, 0, 0, "getnameinfo failed: %s", gai_strerror(rval)); } if (header->version == UFTP_VER_NUM) { version = header->version; group = find_group(ntohl(header->group_id), header->group_inst); } else { log1(0, 0, 0, "Invalid message from %s: not uftp packet " "or invalid version", rxname); continue; } if (packetlen < sizeof(struct uftp_h) + 4) { log1(0, 0, 0, "Invalid packet size from %s: %d", rxname, packetlen); continue; } txseq = htons(header->seq); // A KEY_INFO or ABORT could come from a proxy, so don't check the seq // TODO: need to account for these in the loss history if ((group != NULL) && (header->func != KEYINFO) && (header->func != ABORT)) { if ((int16_t)(group->max_txseq - txseq) > MAXMISORDER) { glog3(group, "seq out of range, dropping"); continue; } if (group->cc_type != CC_NONE) { ecn = ((tos & 0x3) == 3); update_loss_history(group, txseq, packetlen, ecn); } else if ((int16_t)(txseq - group->max_txseq) > 0) { group->max_txseq = txseq; } } if ((header->func == ENCRYPTED) && (group != NULL) && (group->keytype != KEY_NONE)) { if (group->phase == PHASE_REGISTERED) { glog1(group, "Got encrypted packet from %s " "but keys not established", rxname); } if (!validate_and_decrypt(buf, packetlen, &decrypted, &decryptlen, group->keytype, group->groupkey, group->groupsalt, group->ivlen, group->hashtype, group->grouphmackey, group->hmaclen, group->sigtype, group->keyextype, group->server_pubkey, group->server_pubkeylen)) { glog1(group, "Rejecting message from %s: " "decrypt/validate failed", rxname); continue; } func = (uint8_t *)decrypted; message = decrypted; meslen = decryptlen; } else { if ((group != NULL) && (group->keytype != KEY_NONE) && ((header->func == FILEINFO) || (header->func == FILESEG) || (header->func == DONE) || (header->func == DONE_CONF) || ((header->func == ABORT) && (group->phase != PHASE_REGISTERED)))) { glog1(group, "Rejecting %s message from %s: not encrypted", func_name(header->func), rxname); continue; } func = (uint8_t *)&header->func; message = buf + sizeof(struct uftp_h); meslen = packetlen - sizeof(struct uftp_h); } if (group != NULL) { new_grtt = unquantize_grtt(header->grtt); if (fabs(new_grtt - group->grtt) > 0.001) { group->grtt = new_grtt; set_timeout(group, 1); } group->gsize = unquantize_gsize(header->gsize); glog5(group, "grtt: %.3f", group->grtt); } if (header->func == PROXY_KEY) { handle_proxy_key(&src, message, meslen); continue; } if (header->func == HB_RESP) { handle_hb_response(listener, &src, message, meslen, hb_hosts, hbhost_count, privkey[0], privkey_type[0], uid); continue; } if (header->func == ANNOUNCE) { // Ignore any ANNOUNCE for a group we're already handling if (group == NULL) { handle_announce(&src, buf, packetlen, rxtime); } else if (group->phase == PHASE_MIDGROUP) { // Make sure we don't time out while waiting for other // clients to register with the server. set_timeout(group, 0); } } else { if (group == NULL) { // group / file ID not in list continue; } if (group->version != version) { glog1(group, "Version mismatch"); continue; } if (group->src_id != header->src_id) { glog1(group, "Source ID mismatch"); continue; } if (*func == ABORT) { handle_abort(group, message, meslen); continue; } switch (group->phase) { case PHASE_REGISTERED: if (group->keytype != KEY_NONE) { if (*func == KEYINFO) { handle_keyinfo(group, message, meslen, header->src_id); } else { glog1(group, "Expected KEYINFO, got %s", func_name(*func)); } } else if (group->keytype == KEY_NONE) { if (*func == REG_CONF) { handle_regconf(group, message, meslen); } else if (*func == FILEINFO) { handle_fileinfo(group, message, meslen, rxtime); } else { glog1(group, "Expected REG_CONF, got %s", func_name(*func)); } } break; case PHASE_MIDGROUP: if (*func == FILEINFO) { handle_fileinfo(group, message, meslen, rxtime); } else if (*func == KEYINFO) { handle_keyinfo(group, message, meslen, header->src_id); } else if (*func == DONE) { handle_done(group, message, meslen); } else { // Other clients may be still getting earlier files or // setting up, so silently ignore anything unexpected // and reset the timeout. set_timeout(group, 0); } break; case PHASE_RECEIVING: if (*func == FILEINFO) { handle_fileinfo(group, message, meslen, rxtime); } else if (*func == FILESEG) { handle_fileseg(group, message, meslen, txseq); } else if (*func == DONE) { handle_done(group, message, meslen); } else if (*func == CONG_CTRL) { handle_cong_ctrl(group, message, meslen, rxtime); } break; case PHASE_COMPLETE: if (*func == DONE_CONF) { handle_done_conf(group, message, meslen); } break; } } } }
bool Compiler::CompileLazy(Handle<SharedFunctionInfo> shared, int loop_nesting) { CompilationZoneScope zone_scope(DELETE_ON_EXIT); // The VM is in the COMPILER state until exiting this function. VMState state(COMPILER); // Make sure we have an initial stack limit. StackGuard guard; PostponeInterruptsScope postpone; // Compute name, source code and script data. Handle<String> name(String::cast(shared->name())); Handle<Script> script(Script::cast(shared->script())); int start_position = shared->start_position(); int end_position = shared->end_position(); bool is_expression = shared->is_expression(); Counters::total_compile_size.Increment(end_position - start_position); // Generate the AST for the lazily compiled function. The AST may be // NULL in case of parser stack overflow. FunctionLiteral* lit = MakeLazyAST(script, name, start_position, end_position, is_expression); // Check for parse errors. if (lit == NULL) { ASSERT(Top::has_pending_exception()); return false; } // Update the loop nesting in the function literal. lit->set_loop_nesting(loop_nesting); // Measure how long it takes to do the lazy compilation; only take // the rest of the function into account to avoid overlap with the // lazy parsing statistics. HistogramTimerScope timer(&Counters::compile_lazy); // Compile the code. Handle<Code> code = MakeCode(lit, script, Handle<Context>::null(), false); // Check for stack-overflow exception. if (code.is_null()) { Top::StackOverflow(); return false; } #if defined ENABLE_LOGGING_AND_PROFILING || defined ENABLE_OPROFILE_AGENT // Log the code generation. If source information is available include script // name and line number. Check explicit whether logging is enabled as finding // the line number is not for free. if (Logger::is_logging() || OProfileAgent::is_enabled()) { Handle<String> func_name(name->length() > 0 ? *name : shared->inferred_name()); if (script->name()->IsString()) { int line_num = GetScriptLineNumber(script, start_position) + 1; LOG(CodeCreateEvent(Logger::LAZY_COMPILE_TAG, *code, *func_name, String::cast(script->name()), line_num)); OProfileAgent::CreateNativeCodeRegion(*func_name, String::cast(script->name()), line_num, code->instruction_start(), code->instruction_size()); } else { LOG(CodeCreateEvent(Logger::LAZY_COMPILE_TAG, *code, *func_name)); OProfileAgent::CreateNativeCodeRegion(*func_name, code->instruction_start(), code->instruction_size()); } } #endif // Update the shared function info with the compiled code. shared->set_code(*code); // Set the expected number of properties for instances. SetExpectedNofPropertiesFromEstimate(shared, lit->expected_property_count()); // Set the optimication hints after performing lazy compilation, as these are // not set when the function is set up as a lazily compiled function. shared->SetThisPropertyAssignmentsInfo( lit->has_only_this_property_assignments(), lit->has_only_simple_this_property_assignments(), *lit->this_property_assignments()); // Check the function has compiled code. ASSERT(shared->is_compiled()); return true; }
std::string generator_opencl::co(const node& n) { switch (n.type) { case node::entry_point: return "p"; case node::const_var: return std::to_string(n.aux_var); case node::const_bool: return std::to_string(n.aux_bool); case node::const_str: throw std::runtime_error("string encountered"); case node::rotate: return "p_rotate" + pl(n); case node::rotate3: return "p_rotate3(" + co(n.input[0]) + ", (double3)(" + co(n.input[1]) + "," + co(n.input[2]) + "," + co(n.input[3]) + "), " + co(n.input[4]) + ")"; case node::scale: case node::scale3: return "(" + co(n.input[0]) + "/" + co(n.input[1]) + ")"; case node::shift: return "(" + co(n.input[0]) + "+(double2)(" + co(n.input[1]) + "," + co(n.input[2]) + "))"; case node::shift3: return "(" + co(n.input[0]) + "+(double3)(" + co(n.input[1]) + "," + co(n.input[2]) + "," + co(n.input[3]) + "))"; case node::swap: return "p_swap" + pl(n); case node::map: { std::string func_name{std::string("ip_map") + std::to_string(count_++)}; std::stringstream func_body; func_body << "inline double2 " << func_name << " (const double2 p) { return (double2)(" << co(n.input[1]) << ", " << co(n.input[2]) << "); }" << std::endl; functions_.emplace_back(func_body.str()); return func_name + "(" + co(n.input[0]) + ")"; } case node::map3: { std::string func_name{"ip_map3" + std::to_string(count_++)}; std::stringstream func_body; func_body << "inline double3 " << func_name << " (const double3 p) { return (double3)(" << co(n.input[1]) << ", " << co(n.input[2]) << ", " << co(n.input[3]) << "); }" << std::endl; functions_.emplace_back(func_body.str()); return func_name + "(" + co(n.input[0]) + ")"; } case node::turbulence: { std::string func_name("ip_turb" + std::to_string(count_++)); std::stringstream func_body; func_body << "inline double2 " << func_name << " (const double2 p) { return (double2)(" << "p.x+(" << co(n.input[1]) << "), " << "p.y+(" << co(n.input[2]) << ")); }" << std::endl; functions_.emplace_back(func_body.str()); return func_name + "(" + co(n.input[0]) + ")"; } case node::turbulence3: { std::string func_name("ip_turb3" + std::to_string(count_++)); std::stringstream func_body; func_body << "inline double3 " << func_name << " (const double3 p) { return (double3)(" << "p.x+(" << co(n.input[1]) << "), " << "p.y+(" << co(n.input[2]) << "), " << "p.z+(" << co(n.input[3]) << ")); }" << std::endl; functions_.emplace_back(func_body.str()); return func_name + "(" + co(n.input[0]) + ")"; } case node::worley: { std::string func_name("ip_worley" + std::to_string(count_++)); std::stringstream func_body; func_body << "inline double " << func_name << " (const double2 q, uint seed) { " << " double2 p = p_worley(q, seed);" << " return " << co(n.input[1]) << "; }" << std::endl; functions_.emplace_back(func_body.str()); return func_name + "(" + co(n.input[0]) + "," + co(n.input[2]) + ")"; } case node::worley3: { std::string func_name("ip_worley3" + std::to_string(count_++)); std::stringstream func_body; func_body << "inline double " << func_name << " (const double3 q, uint seed) { " << " double3 p = p_worley3(q, seed);" << " return " << co(n.input[1]) << "; }" << std::endl; functions_.emplace_back(func_body.str()); return func_name + "(" + co(n.input[0]) + "," + co(n.input[2]) + ")"; } case node::voronoi: { std::string func_name("ip_voronoi" + std::to_string(count_++)); std::stringstream func_body; func_body << "inline double " << func_name << " (const double2 q, uint seed) { " << " double2 p = p_voronoi(q, seed);" << " return " << co(n.input[1]) << "; }" << std::endl; functions_.emplace_back(func_body.str()); return func_name + "(" + co(n.input[0]) + "," + co(n.input[2]) + ")"; } case node::angle: return "p_angle" + pl(n); case node::chebyshev: return "p_chebyshev" + pl(n); case node::chebyshev3: return "p_chebyshev3" + pl(n); case node::checkerboard: return "p_checkerboard" + pl(n); case node::checkerboard3: return "p_checkerboard3" + pl(n); case node::distance: case node::distance3: return "length" + pl(n); case node::manhattan: return "p_manhattan" + pl(n); case node::manhattan3: return "p_manhattan3" + pl(n); case node::perlin: return "p_perlin" + pl(n); case node::perlin3: return "p_perlin3" + pl(n); case node::simplex: return "p_simplex" + pl(n); case node::simplex3: return "p_simplex3" + pl(n); case node::opensimplex: return "p_opensimplex" + pl(n); case node::opensimplex3: return "p_opensimplex3" + pl(n); case node::x: return co(n.input[0]) + ".x"; case node::y: return co(n.input[0]) + ".y"; case node::z: return co(n.input[0]) + ".z"; case node::xy: return co(n.input[0]) + ".xy"; case node::zplane: return "(double3)(" + co(n.input[0]) + "," + co(n.input[1]) + ")"; case node::add: return "(" + co(n.input[0]) + "+" + co(n.input[1]) + ")"; case node::sub: return "(" + co(n.input[0]) + "-" + co(n.input[1]) + ")"; case node::mul: return "(" + co(n.input[0]) + "*" + co(n.input[1]) + ")"; case node::div: return "(" + co(n.input[0]) + "/" + co(n.input[1]) + ")"; case node::abs: return "fabs" + pl(n); case node::blend: return "p_blend" + pl(n); case node::cos: return "cospi" + pl(n); case node::min: return "fmin" + pl(n); case node::max: return "fmax" + pl(n); case node::neg: return "-" + co(n.input[0]); case node::pow: { if (n.input[1].is_const) { double exp(std::floor(n.input[1].aux_var)); if (std::abs(exp - n.input[1].aux_var) < 1e-9) return "pown(" + co(n.input[0]) + "," + std::to_string((int)exp) + ")"; } return "pow" + pl(n); } case node::round: return "round" + pl(n); case node::saw: return "p_saw" + pl(n); case node::sin: return "sinpi" + pl(n); case node::sqrt: return "sqrt" + pl(n); case node::tan: return "tanpi" + pl(n); case node::band: return co(n.input[0]) + "&&" + co(n.input[1]); case node::bor: return co(n.input[0]) + "||" + co(n.input[1]); case node::bxor: return "((" + co(n.input[0]) + ")!=(" + co(n.input[1]) + "))"; case node::bnot: return "!" + co(n.input[0]); case node::is_equal: return co(n.input[0]) + "==" + co(n.input[1]); case node::is_greaterthan: return co(n.input[0]) + ">" + co(n.input[1]); case node::is_gte: return co(n.input[0]) + ">=" + co(n.input[1]); case node::is_lessthan: return co(n.input[0]) + "<" + co(n.input[1]); case node::is_lte: return co(n.input[0]) + "<=" + co(n.input[1]); case node::is_in_circle: return "p_is_in_circle" + pl(n); case node::is_in_rectangle: return "p_is_in_rectangle" + pl(n); case node::then_else: return "(" + co(n.input[0]) + ")?(" + co(n.input[1]) + "):(" + co(n.input[2]) + ")"; case node::fractal: { assert(n.input.size() == 5); if (!n.input[2].is_const) throw std::runtime_error( "fractal octave count must be a constexpr"); int octaves(std::min<int>(n.input[2].aux_var, OPENCL_OCTAVES_LIMIT)); std::string func_name("ip_fractal_" + std::to_string(count_++)); std::stringstream func_body; func_body << "double " << func_name << " (double2 p, const double lac, const double per) {" << "double result = 0.0; double div = 0.0; double step = 1.0;" << "for(int i = 0; i < " << octaves << "; ++i)" << "{" << " result += " << co(n.input[1]) << " * step;" << " div += step;" << " step *= per;" << " p *= lac;" << " p.x += 12345.0;" << "}" << "return result / div;" << "}"; functions_.emplace_back(func_body.str()); return func_name + "(" + co(n.input[0]) + "," + co(n.input[3]) + "," + co(n.input[4]) + ")"; } case node::fractal3: { assert(n.input.size() == 5); if (!n.input[2].is_const) throw std::runtime_error( "fractal octave count must be a constexpr"); int octaves = std::min<int>(n.input[2].aux_var, OPENCL_OCTAVES_LIMIT); std::string func_name{"ip_fractal3_" + std::to_string(count_++)}; std::stringstream func_body; func_body << "double " << func_name << " (double3 p, const double lac, const double per) {" << "double result = 0.0; double div = 0.0; double step = 1.0;" << "for(int i = 0; i < " << octaves << "; ++i)" << "{" << " result += " << co(n.input[1]) << " * step;" << " div += step;" << " step *= per;" << " p *= lac;" << " p.x += 12345.0;" << "}" << "return result / div;" << "}"; functions_.emplace_back(func_body.str()); return func_name + "(" + co(n.input[0]) + "," + co(n.input[3]) + "," + co(n.input[4]) + ")"; } case node::lambda_: { assert(n.input.size() == 2); std::string func_name{"ip_lambda_" + std::to_string(count_++)}; std::string type{type_string(n.input[0])}; std::stringstream func_body; func_body << "double " << func_name << " (" << type << " p) {" << "return " << co(n.input[1]) << ";}" << std::endl; functions_.emplace_back(func_body.str()); return func_name + "(" + co(n.input[0]) + ")"; } case node::external_: throw std::runtime_error("OpenCL @external not implemented yet"); case node::curve_linear: throw std::runtime_error("OpenCL curve_linear not implemented yet"); case node::curve_spline: throw std::runtime_error("OpenCL curve_spline not implemented yet"); case node::png_lookup: throw std::runtime_error("OpenCL png_lookup not implemented yet"); default: throw std::runtime_error("function not implemented in OpenCL yet"); } return std::string(); }
/** * For messages that send a list of clients in the body, append all clients * in the specified state to the packet, then send the message of the given * type when either the body is full or the end of the client list has been * reached. All header fields besides uftp_h.blsize and message.destcount * must be populated before calling. * Returns 1 on success, 0 on fail. */ int send_multiple(const struct finfo_t *finfo, unsigned char *packet, int message, int attempt, uint32_t *addrlist, int state, uint16_t *mes_destcount, int encrypt, const struct sockaddr_in *destaddr, int regconf) { struct uftp_h *header; int hsize, payloadlen; int maxdest, packetcnt, dests, i; unsigned char *mheader, *encpacket, *outpacket; header = (struct uftp_h *)packet; mheader = packet + sizeof(struct uftp_h); hsize = (unsigned char *)addrlist - mheader; maxdest = ((encrypt ? encpayloadsize : payloadsize) - hsize) / sizeof(struct in_addr); packetcnt = 1; if (encrypt) { encpacket = calloc(mtu + keylen, 1); if (encpacket == NULL) { syserror(0, 0, "calloc failed!"); exit(1); } } else { encpacket = NULL; } for (i = 0, dests = 0; i < destcount; i++) { if (message == REG_CONF) { // Only send REG_CONF for a particular client if either it's // behind a proxy or we're sending them to everyone. // Also, don't send if we already sent one and we haven't // gotten another REGISTER if ((destlist[i].status == state) && (!finfo->deststate[i].conf_sent) && (regconf || (destlist[i].proxyidx != -1))) { addrlist[dests++] = destlist[i].addr.s_addr; finfo->deststate[i].conf_sent = 1; } } else if (message == DONE_CONF) { // As with REG_CONF, don't send a DONE_CONF for a client // if we already sent one and we haven't gotten another COMPLETE if ((destlist[i].status == state) && (!finfo->deststate[i].conf_sent)) { addrlist[dests++] = destlist[i].addr.s_addr; finfo->deststate[i].conf_sent = 1; } } else if (destlist[i].status == state) { addrlist[dests++] = destlist[i].addr.s_addr; } if ((dests >= maxdest) || ((i == destcount - 1) && (dests > 0))) { payloadlen = hsize + (dests * sizeof(uint32_t)); *mes_destcount = htons(dests); if (encrypt) { if (!encrypt_and_sign(packet, &encpacket, payloadlen, mtu, keytype, groupkey, groupsalt, ivlen, hashtype, grouphmackey, hmaclen, sigtype, privkey, rsalen)) { log0(0, 0, "Error encrypting %s", func_name(message)); free(encpacket); return 0; } outpacket = encpacket; payloadlen = ntohs(((struct uftp_h *)outpacket)->blsize); } else { outpacket = packet; header->blsize = htons(payloadlen); } log2(0, 0, "Sending %s %d.%d", func_name(message), attempt, packetcnt); log4(0, 0, "Sending to %08X", ntohl(destaddr->sin_addr.s_addr)); if (nb_sendto(sock, outpacket, payloadlen + sizeof(struct uftp_h),0, (struct sockaddr *)destaddr, sizeof(*destaddr)) == SOCKET_ERROR) { sockerror(0, 0, "Error sending %s", func_name(message)); sleep(1); free(encpacket); return 0; } if (packet_wait) usleep(packet_wait); memset(addrlist, 0, maxdest * sizeof(uint32_t)); dests = 0; packetcnt++; } } free(encpacket); return 1; }
/** * Check a transfer phase message and pass to appropriate message handler, * decrypting first if necessary * Returns 1 on success, 0 on error */ int handle_transfer_phase(const unsigned char *packet, unsigned char *decrypted, const struct sockaddr_in *receiver, int blocks_this_sec, int section_offset, int pass, int section, struct finfo_t *finfo) { struct uftp_h *header; const unsigned char *message; int hostidx; unsigned int decryptlen, meslen; uint8_t *func; struct in_addr srcaddr; header = (struct uftp_h *)packet; hostidx = find_client(header->srcaddr); srcaddr.s_addr = header->srcaddr; if ((keytype != KEY_NONE) && (header->func == ENCRYPTED)) { if (hostidx == -1) { log1(0, 0, "Host %s not in host list", inet_ntoa(srcaddr)); send_abort(finfo, "Not in host list", receiver, &srcaddr, 0, 0); return 0; } if (!validate_and_decrypt(packet, &decrypted, &decryptlen, mtu, keytype, groupkey, groupsalt, ivlen, hashtype, grouphmackey, hmaclen, sigtype, destlist[hostidx].encinfo->pubkey, destlist[hostidx].encinfo->pubkeylen)) { log1(0, 0, "Rejecting message from %s: decrypt/validate failed", destlist[hostidx].name); return 0; } func = (uint8_t *)decrypted; message = decrypted; meslen = decryptlen; } else { if ((keytype != KEY_NONE) && ((header->func == PRSTATUS) || (header->func == STATUS) || (header->func == COMPLETE) || (header->func == ABORT))) { log1(0, 0, "Rejecting %s message from %s: not encrypted", func_name(header->func), inet_ntoa(srcaddr)); return 0; } func = (uint8_t *)&header->func; message = packet + sizeof(struct uftp_h); meslen = ntohs(header->blsize); } if (*func == ABORT) { handle_abort(message, meslen, hostidx, finfo, &srcaddr); } else if (hostidx == -1) { log1(0, 0, "Host %s not in host list", inet_ntoa(srcaddr)); send_abort(finfo, "Not in host list", receiver, &srcaddr, 0, 0); } else { switch (destlist[hostidx].status) { case DEST_ACTIVE: if (*func == STATUS) { handle_status(message, meslen, finfo, hostidx, blocks_this_sec, section_offset, pass, section); } else if (*func == COMPLETE) { handle_complete(message, meslen, finfo, hostidx); } else if ((destlist[hostidx].clientcnt != -1) && (*func == PRSTATUS)) { handle_prstatus(message, meslen, finfo, hostidx, blocks_this_sec, section_offset, pass, section); } else { log1(0, 0, "Received invalid message %s from %s", func_name(*func), destlist[hostidx].name); } break; case DEST_STATUS: if (*func == COMPLETE) { handle_complete(message, meslen, finfo, hostidx); } else if (*func == STATUS) { handle_status(message, meslen, finfo, hostidx, blocks_this_sec, section_offset, pass, section); } else { log1(0, 0, "Received invalid message %s from %s", func_name(*func), destlist[hostidx].name); } break; case DEST_DONE: if (*func == COMPLETE) { handle_complete(message, meslen, finfo, hostidx); } else { log1(0, 0, "Received invalid message %s from %s", func_name(*func), destlist[hostidx].name); } break; } } return 1; }
/** * This is the main message reading loop. Messages are read, validated, * decrypted if necessary, then passed to the appropriate routine for handling. */ void mainloop() { struct uftp_h *header; unsigned char *buf, *decrypted, *message; int packetlen, listidx, hostidx, i; unsigned int decryptlen, meslen; uint8_t *func; struct sockaddr_in src; struct in_addr srcaddr; struct timeval *tv; const int bsize = 9000; // Roughly size of ethernet jumbo frame log0(0, 0, "%s", VERSIONSTR); for (i = 0; i < key_count; i++) { log(0, 0, "Loaded key with fingerprint %s", print_key_fingerprint(privkey[i])); } buf = calloc(bsize, 1); decrypted = calloc(bsize, 1); if ((buf == NULL) || (decrypted == NULL)) { syserror(0, 0, "calloc failed!"); exit(1); } header = (struct uftp_h *)buf; while (1) { tv = getrecenttimeout(); if (read_packet(listener, &src, buf, &packetlen, bsize, tv) <= 0) { continue; } if ((header->uftp_id != UFTP_VER_NUM) && (header->uftp_id != UFTP_3_0_VER)) { log(0, 0, "Invalid message from %s: not uftp packet " "or invalid version", inet_ntoa(src.sin_addr)); continue; } if (packetlen != sizeof(struct uftp_h) + ntohs(header->blsize)) { log(0, 0, "Invalid packet size from %s: got %d, expected %d", inet_ntoa(src.sin_addr), packetlen, sizeof(struct uftp_h) + ntohs(header->blsize)); continue; } if ((src.sin_addr.s_addr == out_addr.s_addr) && (src.sin_port == htons(port))) { // Packet from self -- drop continue; } if (header->func == HB_REQ) { handle_hb_request(&src, buf); continue; } if (header->func == HB_RESP) { handle_hb_response(listener, &src, buf, hb_hosts, hbhost_count, noname, privkey[0]); continue; } if (header->func == KEY_REQ) { handle_key_req(&src, buf); continue; } if (header->func == PROXY_KEY) { // Only clients handle these, so drop continue; } if ((proxy_type == SERVER_PROXY) && (down_addr.sin_addr.s_addr == INADDR_ANY)) { log(0, 0, "Rejecting message from %s: downstream address " "not established", inet_ntoa(src.sin_addr)); continue; } listidx = find_group(ntohl(header->group_id)); if (header->func == ANNOUNCE) { handle_announce(listidx, &src, buf); } else { if (listidx == -1) { continue; } if (proxy_type == SERVER_PROXY) { // Server proxies don't do anything outside of an ANNOUNCE. // Just send it on through. forward_message(listidx, &src, buf); continue; } if (header->func == ABORT) { handle_abort(listidx, &src, buf); continue; } if (!memcmp(&src, &group_list[listidx].up_addr, sizeof(src))) { // Downstream message if (header->func == KEYINFO) { handle_keyinfo(listidx, buf); } else if ((header->func == REG_CONF) && (group_list[listidx].keytype != KEY_NONE)) { handle_regconf(listidx, buf); } else { // If we don't need to process the message, don't bother // decrypting anything. Just forward it on. forward_message(listidx, &src, buf); } } else { // Upstream message // Decrypt first if necessary hostidx = find_client(listidx, header->srcaddr); if ((hostidx != -1) && (header->func == ENCRYPTED) && (group_list[listidx].keytype != KEY_NONE)) { if (!validate_and_decrypt(buf, &decrypted, &decryptlen, group_list[listidx].mtu,group_list[listidx].keytype, group_list[listidx].groupkey, group_list[listidx].groupsalt, group_list[listidx].ivlen, group_list[listidx].hashtype, group_list[listidx].grouphmackey, group_list[listidx].hmaclen, group_list[listidx].sigtype, group_list[listidx].destinfo[hostidx].pubkey, group_list[listidx].destinfo[hostidx].pubkeylen)) { log(ntohl(header->group_id), 0, "Rejecting message " "from %s: decrypt/validate failed", inet_ntoa(src.sin_addr)); continue; } func = (uint8_t *)decrypted; message = decrypted; meslen = decryptlen; } else { if ((hostidx != -1) && (group_list[listidx].keytype != KEY_NONE) && ((header->func == INFO_ACK) || (header->func == STATUS) || (header->func == COMPLETE))) { log(ntohl(header->group_id), 0, "Rejecting %s message " "from %s: not encrypted", func_name(header->func), inet_ntoa(src.sin_addr)); continue; } func = (uint8_t *)&header->func; message = buf + sizeof(struct uftp_h); meslen = ntohs(header->blsize); } if ((hostidx == -1) && (header->srcaddr == 0)) { srcaddr = src.sin_addr; } else { srcaddr.s_addr = header->srcaddr; } switch (*func) { case REGISTER: handle_register(listidx, hostidx, message, meslen, srcaddr.s_addr); break; case CLIENT_KEY: handle_clientkey(listidx, hostidx, message, meslen, srcaddr.s_addr); break; case INFO_ACK: handle_info_ack(listidx, hostidx, message, meslen); break; case STATUS: handle_status(listidx, hostidx, message, meslen); break; case COMPLETE: handle_complete(listidx, hostidx, message, meslen); break; default: forward_message(listidx, &src, buf); break; } } } } }