int main(int argc, char** argv) { #ifdef Log_KEYS fprintf(stderr, "Log_LEVEL = KEYS, EXPECT TO SEE PRIVATE KEYS IN YOUR LOGS!\n"); #endif Crypto_init(); assert(argc > 0); if (argc == 1) { // no arguments if (isatty(STDIN_FILENO)) { // We were started from a terminal // The chances an user wants to type in a configuration // bij hand are pretty slim so we show him the usage return usage(argv[0]); } else { // We assume stdin is a configuration file and that we should // start routing } } if (argc == 2) { // one argument if (strcmp(argv[1], "--help") == 0) { return usage(argv[0]); } else if (strcmp(argv[1], "--genconf") == 0) { return genconf(); } else if (strcmp(argv[1], "--getcmds") == 0) { // Performed after reading the configuration } else if (strcmp(argv[1], "--pidfile") == 0) { // Performed after reading the configuration } else { fprintf(stderr, "%s: unrecognized option '%s'\n", argv[0], argv[1]); fprintf(stderr, "Try `%s --help' for more information.\n", argv[0]); return -1; } } if (argc > 2) { // more than one argument? fprintf(stderr, "%s: too many arguments\n", argv[0]); fprintf(stderr, "Try `%s --help' for more information.\n", argv[0]); return -1; } struct Context context; memset(&context, 0, sizeof(struct Context)); context.base = event_base_new(); // Allow it to allocate 4MB context.allocator = MallocAllocator_new(1<<22); struct Reader* reader = FileReader_new(stdin, context.allocator); Dict config; if (JsonBencSerializer_get()->parseDictionary(reader, context.allocator, &config)) { fprintf(stderr, "Failed to parse configuration.\n"); return -1; } if (argc == 2 && strcmp(argv[1], "--getcmds") == 0) { return getcmds(&config); } if (argc == 2 && strcmp(argv[1], "--pidfile") == 0) { pidfile(&config); return 0; } char* user = setUser(Dict_getList(&config, BSTR("security"))); // Admin Dict* adminConf = Dict_getDict(&config, BSTR("admin")); if (adminConf) { admin(adminConf, user, &context); } // Logging struct Writer* logwriter = FileWriter_new(stdout, context.allocator); struct Log logger = { .writer = logwriter }; context.logger = &logger; struct Address myAddr; uint8_t privateKey[32]; parsePrivateKey(&config, &myAddr, privateKey); context.eHandler = AbortHandler_INSTANCE; context.switchCore = SwitchCore_new(context.logger, context.allocator); context.ca = CryptoAuth_new(&config, context.allocator, privateKey, context.base, context.logger); context.registry = DHTModules_new(context.allocator); ReplyModule_register(context.registry, context.allocator); // Router Dict* routerConf = Dict_getDict(&config, BSTR("router")); registerRouter(routerConf, myAddr.key, &context); SerializationModule_register(context.registry, context.allocator); // Authed passwords. List* authedPasswords = Dict_getList(&config, BSTR("authorizedPasswords")); if (authedPasswords) { authorizedPasswords(authedPasswords, &context); } // Interfaces. Dict* interfaces = Dict_getDict(&config, BSTR("interfaces")); Dict* udpConf = Dict_getDict(interfaces, BSTR("UDPInterface")); if (udpConf) { configureUDP(udpConf, &context); } if (udpConf == NULL) { fprintf(stderr, "No interfaces configured to connect to.\n"); return -1; } // pid file String* pidFile = Dict_getString(&config, BSTR("pidFile")); if (pidFile) { Log_info1(context.logger, "Writing pid of process to [%s].\n", pidFile->bytes); FILE* pf = fopen(pidFile->bytes, "w"); if (!pf) { Log_critical2(context.logger, "Failed to open pid file [%s] for writing, errno=%d\n", pidFile->bytes, errno); return -1; } fprintf(pf, "%d", getpid()); fclose(pf); } Ducttape_register(&config, privateKey, context.registry, context.routerModule, context.routerIf, context.switchCore, context.base, context.allocator, context.logger); uint8_t address[53]; Base32_encode(address, 53, myAddr.key, 32); Log_info1(context.logger, "Your address is: %s.k\n", address); uint8_t myIp[40]; Address_printIp(myIp, &myAddr); Log_info1(context.logger, "Your IPv6 address is: %s\n", myIp); // Security. security(Dict_getList(&config, BSTR("security")), context.logger, context.eHandler); event_base_loop(context.base, 0); // Never reached. return 0; }
static void add_solv(const char *fn, t_atoms *atoms, rvec **x, rvec **v, real **r, int ePBC, matrix box, gmx_atomprop_t aps, real r_distance, int *atoms_added, int *residues_added, real rshell, int max_sol, const output_env_t oenv) { int i, nmol; ivec n_box; char filename[STRLEN]; char title_solvt[STRLEN]; t_atoms *atoms_solvt; rvec *x_solvt, *v_solvt = NULL; real *r_solvt; int ePBC_solvt; matrix box_solvt; int onr, onres; char *lfn; lfn = gmxlibfn(fn); strncpy(filename, lfn, STRLEN); sfree(lfn); snew(atoms_solvt, 1); get_stx_coordnum(filename, &(atoms_solvt->nr)); if (atoms_solvt->nr == 0) { gmx_fatal(FARGS, "No solvent in %s, please check your input\n", filename); } snew(x_solvt, atoms_solvt->nr); if (v) { snew(v_solvt, atoms_solvt->nr); } snew(r_solvt, atoms_solvt->nr); snew(atoms_solvt->resinfo, atoms_solvt->nr); snew(atoms_solvt->atomname, atoms_solvt->nr); snew(atoms_solvt->atom, atoms_solvt->nr); atoms_solvt->pdbinfo = NULL; fprintf(stderr, "Reading solvent configuration%s\n", v_solvt ? " and velocities" : ""); read_stx_conf(filename, title_solvt, atoms_solvt, x_solvt, v_solvt, &ePBC_solvt, box_solvt); fprintf(stderr, "\"%s\"\n", title_solvt); fprintf(stderr, "solvent configuration contains %d atoms in %d residues\n", atoms_solvt->nr, atoms_solvt->nres); fprintf(stderr, "\n"); /* apply pbc for solvent configuration for whole molecules */ rm_res_pbc(atoms_solvt, x_solvt, box_solvt); /* initialise van der waals arrays of solvent configuration */ mk_vdw(atoms_solvt, r_solvt, aps, r_distance); /* calculate the box multiplication factors n_box[0...DIM] */ nmol = 1; for (i = 0; (i < DIM); i++) { n_box[i] = 1; while (n_box[i]*box_solvt[i][i] < box[i][i]) { n_box[i]++; } nmol *= n_box[i]; } fprintf(stderr, "Will generate new solvent configuration of %dx%dx%d boxes\n", n_box[XX], n_box[YY], n_box[ZZ]); /* realloc atoms_solvt for the new solvent configuration */ srenew(atoms_solvt->resinfo, atoms_solvt->nres*nmol); srenew(atoms_solvt->atomname, atoms_solvt->nr*nmol); srenew(atoms_solvt->atom, atoms_solvt->nr*nmol); srenew(x_solvt, atoms_solvt->nr*nmol); if (v_solvt) { srenew(v_solvt, atoms_solvt->nr*nmol); } srenew(r_solvt, atoms_solvt->nr*nmol); /* generate a new solvent configuration */ genconf(atoms_solvt, x_solvt, v_solvt, r_solvt, box_solvt, n_box); #ifdef DEBUG print_stat(x_solvt, atoms_solvt->nr, box_solvt); #endif #ifdef DEBUG print_stat(x_solvt, atoms_solvt->nr, box_solvt); #endif /* Sort the solvent mixture, not the protein... */ sort_molecule(&atoms_solvt, x_solvt, v_solvt, r_solvt); /* add the two configurations */ onr = atoms->nr; onres = atoms->nres; add_conf(atoms, x, v, r, TRUE, ePBC, box, FALSE, atoms_solvt, x_solvt, v_solvt, r_solvt, TRUE, rshell, max_sol, oenv); *atoms_added = atoms->nr-onr; *residues_added = atoms->nres-onres; sfree(x_solvt); sfree(r_solvt); fprintf(stderr, "Generated solvent containing %d atoms in %d residues\n", *atoms_added, *residues_added); }
static char *insert_mols(char *mol_insrt,int nmol_insrt,int ntry,int seed, t_atoms *atoms,rvec **x,real **r,int ePBC,matrix box, gmx_atomprop_t aps,real r_distance,real rshell) { t_pbc pbc; static char *title_insrt; t_atoms atoms_insrt; rvec *x_insrt,*x_n; real *r_insrt; int ePBC_insrt; matrix box_insrt; int i,mol,onr; real alfa,beta,gamma; rvec offset_x; int try; set_pbc(&pbc,ePBC,box); /* read number of atoms of insert molecules */ get_stx_coordnum(mol_insrt,&atoms_insrt.nr); if (atoms_insrt.nr == 0) gmx_fatal(FARGS,"No molecule in %s, please check your input\n",mol_insrt); /* allocate memory for atom coordinates of insert molecules */ snew(x_insrt,atoms_insrt.nr); snew(r_insrt,atoms_insrt.nr); snew(atoms_insrt.resname,atoms_insrt.nr); snew(atoms_insrt.atomname,atoms_insrt.nr); snew(atoms_insrt.atom,atoms_insrt.nr); atoms_insrt.pdbinfo = NULL; snew(x_n,atoms_insrt.nr); snew(title_insrt,STRLEN); /* read residue number, residue names, atomnames, coordinates etc. */ fprintf(stderr,"Reading molecule configuration \n"); read_stx_conf(mol_insrt,title_insrt,&atoms_insrt,x_insrt,NULL, &ePBC_insrt,box_insrt); fprintf(stderr,"%s\nContaining %d atoms in %d residue\n", title_insrt,atoms_insrt.nr,atoms_insrt.nres); srenew(atoms_insrt.resname,atoms_insrt.nres); /* initialise van der waals arrays of insert molecules */ mk_vdw(&atoms_insrt,r_insrt,aps,r_distance); srenew(atoms->resname,(atoms->nres+nmol_insrt)); srenew(atoms->atomname,(atoms->nr+atoms_insrt.nr*nmol_insrt)); srenew(atoms->atom,(atoms->nr+atoms_insrt.nr*nmol_insrt)); srenew(*x,(atoms->nr+atoms_insrt.nr*nmol_insrt)); srenew(*r,(atoms->nr+atoms_insrt.nr*nmol_insrt)); try=mol=0; while ((mol < nmol_insrt) && (try < ntry*nmol_insrt)) { fprintf(stderr,"\rTry %d",try++); for (i=0;(i<atoms_insrt.nr);i++) { if (atoms_insrt.atom[i].resnr!=0) gmx_fatal(FARGS,"more then one residue in insert molecules\n" "program terminated\n"); copy_rvec(x_insrt[i],x_n[i]); } alfa=2*M_PI*rando(&seed); beta=2*M_PI*rando(&seed); gamma=2*M_PI*rando(&seed); rotate_conf(atoms_insrt.nr,x_n,NULL,alfa,beta,gamma); offset_x[XX]=box[XX][XX]*rando(&seed); offset_x[YY]=box[YY][YY]*rando(&seed); offset_x[ZZ]=box[ZZ][ZZ]*rando(&seed); gen_box(0,atoms_insrt.nr,x_n,box_insrt,offset_x,TRUE); if (!in_box(&pbc,x_n[0]) || !in_box(&pbc,x_n[atoms_insrt.nr-1])) continue; onr=atoms->nr; add_conf(atoms,x,NULL,r,FALSE,ePBC,box,TRUE, &atoms_insrt,x_n,NULL,r_insrt,FALSE,rshell,0); if (atoms->nr==(atoms_insrt.nr+onr)) { mol++; fprintf(stderr," success (now %d atoms)!",atoms->nr); } } srenew(atoms->resname, atoms->nres); srenew(atoms->atomname, atoms->nr); srenew(atoms->atom, atoms->nr); srenew(*x, atoms->nr); srenew(*r, atoms->nr); fprintf(stderr,"\n"); /* print number of molecules added */ fprintf(stderr,"Added %d molecules (out of %d requested) of %s\n", mol,nmol_insrt,*atoms_insrt.resname[0]); return title_insrt; } static void add_solv(char *fn,t_atoms *atoms,rvec **x,rvec **v,real **r, int ePBC,matrix box, gmx_atomprop_t aps,real r_distance,int *atoms_added, int *residues_added,real rshell,int max_sol) { int i,nmol; ivec n_box; char filename[STRLEN]; char title_solvt[STRLEN]; t_atoms *atoms_solvt; rvec *x_solvt,*v_solvt=NULL; real *r_solvt; int ePBC_solvt; matrix box_solvt; int onr,onres; strncpy(filename,libfn(fn),STRLEN); snew(atoms_solvt,1); get_stx_coordnum(filename,&(atoms_solvt->nr)); if (atoms_solvt->nr == 0) gmx_fatal(FARGS,"No solvent in %s, please check your input\n",filename); snew(x_solvt,atoms_solvt->nr); if (v) snew(v_solvt,atoms_solvt->nr); snew(r_solvt,atoms_solvt->nr); snew(atoms_solvt->resname,atoms_solvt->nr); snew(atoms_solvt->atomname,atoms_solvt->nr); snew(atoms_solvt->atom,atoms_solvt->nr); atoms_solvt->pdbinfo = NULL; fprintf(stderr,"Reading solvent configuration%s\n", v_solvt?" and velocities":""); read_stx_conf(filename,title_solvt,atoms_solvt,x_solvt,v_solvt, &ePBC_solvt,box_solvt); fprintf(stderr,"\"%s\"\n",title_solvt); fprintf(stderr,"solvent configuration contains %d atoms in %d residues\n", atoms_solvt->nr,atoms_solvt->nres); fprintf(stderr,"\n"); /* apply pbc for solvent configuration for whole molecules */ rm_res_pbc(atoms_solvt,x_solvt,box_solvt); /* initialise van der waals arrays of solvent configuration */ mk_vdw(atoms_solvt,r_solvt,aps,r_distance); /* calculate the box multiplication factors n_box[0...DIM] */ nmol=1; for (i=0; (i < DIM);i++) { n_box[i] = 1; while (n_box[i]*box_solvt[i][i] < box[i][i]) n_box[i]++; nmol*=n_box[i]; } fprintf(stderr,"Will generate new solvent configuration of %dx%dx%d boxes\n", n_box[XX],n_box[YY],n_box[ZZ]); /* realloc atoms_solvt for the new solvent configuration */ srenew(atoms_solvt->resname,atoms_solvt->nres*nmol); srenew(atoms_solvt->atomname,atoms_solvt->nr*nmol); srenew(atoms_solvt->atom,atoms_solvt->nr*nmol); srenew(x_solvt,atoms_solvt->nr*nmol); if (v_solvt) srenew(v_solvt,atoms_solvt->nr*nmol); srenew(r_solvt,atoms_solvt->nr*nmol); /* generate a new solvent configuration */ genconf(atoms_solvt,x_solvt,v_solvt,r_solvt,box_solvt,n_box); #ifdef DEBUG print_stat(x_solvt,atoms_solvt->nr,box_solvt); #endif #ifdef DEBUG print_stat(x_solvt,atoms_solvt->nr,box_solvt); #endif /* Sort the solvent mixture, not the protein... */ sort_molecule(&atoms_solvt,x_solvt,v_solvt,r_solvt); /* add the two configurations */ onr=atoms->nr; onres=atoms->nres; add_conf(atoms,x,v,r,TRUE,ePBC,box,FALSE, atoms_solvt,x_solvt,v_solvt,r_solvt,TRUE,rshell,max_sol); *atoms_added=atoms->nr-onr; *residues_added=atoms->nres-onres; sfree(x_solvt); sfree(r_solvt); fprintf(stderr,"Generated solvent containing %d atoms in %d residues\n", *atoms_added,*residues_added); }
int main(int argc, char** argv) { #ifdef Log_KEYS fprintf(stderr, "Log_LEVEL = KEYS, EXPECT TO SEE PRIVATE KEYS IN YOUR LOGS!\n"); #endif Assert_true(argc > 0); struct Except* eh = NULL; // Allow it to allocate 4MB struct Allocator* allocator = MallocAllocator_new(1<<22); struct Random* rand = Random_new(allocator, NULL, eh); struct EventBase* eventBase = EventBase_new(allocator); if (argc == 2) { // one argument if (strcmp(argv[1], "--help") == 0) { return usage(argv[0]); } else if (strcmp(argv[1], "--genconf") == 0) { return genconf(rand); } else if (strcmp(argv[1], "--pidfile") == 0) { // Performed after reading the configuration } else if (strcmp(argv[1], "--reconf") == 0) { // Performed after reading the configuration } else if (strcmp(argv[1], "--bench") == 0) { return benchmark(); } else if (strcmp(argv[1], "--version") == 0) { //printf("Version ID: %s\n", RouterModule_gitVersion()); return 0; } else { fprintf(stderr, "%s: unrecognized option '%s'\n", argv[0], argv[1]); fprintf(stderr, "Try `%s --help' for more information.\n", argv[0]); return -1; } } else if (argc > 2) { // more than one argument? fprintf(stderr, "%s: too many arguments\n", argv[0]); fprintf(stderr, "Try `%s --help' for more information.\n", argv[0]); return -1; } if (isatty(STDIN_FILENO)) { // We were started from a terminal // The chances an user wants to type in a configuration // bij hand are pretty slim so we show him the usage return usage(argv[0]); } else { // We assume stdin is a configuration file and that we should // start routing } struct Reader* stdinReader = FileReader_new(stdin, allocator); Dict config; if (JsonBencSerializer_get()->parseDictionary(stdinReader, allocator, &config)) { fprintf(stderr, "Failed to parse configuration.\n"); return -1; } struct Writer* logWriter = FileWriter_new(stdout, allocator); struct Log* logger = WriterLog_new(logWriter, allocator); // --------------------- Setup Pipes to Angel --------------------- // int pipeToAngel[2]; int pipeFromAngel[2]; if (Pipe_createUniPipe(pipeToAngel) || Pipe_createUniPipe(pipeFromAngel)) { Except_raise(eh, -1, "Failed to create pipes to angel [%s]", Errno_getString()); } char pipeToAngelStr[8]; snprintf(pipeToAngelStr, 8, "%d", pipeToAngel[0]); char pipeFromAngelStr[8]; snprintf(pipeFromAngelStr, 8, "%d", pipeFromAngel[1]); char* args[] = { "angel", pipeToAngelStr, pipeFromAngelStr, NULL }; // --------------------- Spawn Angel --------------------- // String* privateKey = Dict_getString(&config, String_CONST("privateKey")); String* corePath = getCorePath(allocator); if (!corePath) { Except_raise(eh, -1, "Can't find a usable cjdns core executable, " "make sure it is in the same directory as cjdroute"); } if (!privateKey) { Except_raise(eh, -1, "Need to specify privateKey."); } Log_info(logger, "Forking angel to background."); Process_spawn(corePath->bytes, args); // --------------------- Get Admin --------------------- // Dict* configAdmin = Dict_getDict(&config, String_CONST("admin")); String* adminPass = Dict_getString(configAdmin, String_CONST("password")); String* adminBind = Dict_getString(configAdmin, String_CONST("bind")); if (!adminPass) { adminPass = String_newBinary(NULL, 32, allocator); Random_base32(rand, (uint8_t*) adminPass->bytes, 32); adminPass->len = strlen(adminPass->bytes); } if (!adminBind) { adminBind = String_new("127.0.0.1:0", allocator); } // --------------------- Get user for angel to setuid() ---------------------- // String* securityUser = NULL; List* securityConf = Dict_getList(&config, String_CONST("security")); for (int i = 0; i < List_size(securityConf); i++) { securityUser = Dict_getString(List_getDict(securityConf, i), String_CONST("setuser")); if (securityUser) { int64_t* ea = Dict_getInt(List_getDict(securityConf, i), String_CONST("exemptAngel")); if (ea && *ea) { securityUser = NULL; } break; } } // --------------------- Pre-Configure Angel ------------------------- // Dict* preConf = Dict_new(allocator); Dict* adminPreConf = Dict_new(allocator); Dict_putDict(preConf, String_CONST("admin"), adminPreConf, allocator); Dict_putString(adminPreConf, String_CONST("core"), corePath, allocator); Dict_putString(preConf, String_CONST("privateKey"), privateKey, allocator); Dict_putString(adminPreConf, String_CONST("bind"), adminBind, allocator); Dict_putString(adminPreConf, String_CONST("pass"), adminPass, allocator); if (securityUser) { Dict_putString(adminPreConf, String_CONST("user"), securityUser, allocator); } #define CONFIG_BUFF_SIZE 1024 uint8_t buff[CONFIG_BUFF_SIZE] = {0}; struct Writer* toAngelWriter = ArrayWriter_new(buff, CONFIG_BUFF_SIZE - 1, allocator); if (StandardBencSerializer_get()->serializeDictionary(toAngelWriter, preConf)) { Except_raise(eh, -1, "Failed to serialize pre-configuration"); } write(pipeToAngel[1], buff, toAngelWriter->bytesWritten(toAngelWriter)); Log_keys(logger, "Sent [%s] to angel process.", buff); // --------------------- Get Response from Angel --------------------- // uint32_t amount = Waiter_getData(buff, CONFIG_BUFF_SIZE, pipeFromAngel[0], eventBase, eh); Dict responseFromAngel; struct Reader* responseFromAngelReader = ArrayReader_new(buff, amount, allocator); if (StandardBencSerializer_get()->parseDictionary(responseFromAngelReader, allocator, &responseFromAngel)) { Except_raise(eh, -1, "Failed to parse pre-configuration response [%s]", buff); } // --------------------- Get Admin Addr/Port/Passwd --------------------- // Dict* responseFromAngelAdmin = Dict_getDict(&responseFromAngel, String_CONST("admin")); adminBind = Dict_getString(responseFromAngelAdmin, String_CONST("bind")); if (!adminBind) { Except_raise(eh, -1, "didn't get address and port back from angel"); } struct Sockaddr_storage adminAddr; if (Sockaddr_parse(adminBind->bytes, &adminAddr)) { Except_raise(eh, -1, "Unable to parse [%s] as an ip address port, eg: 127.0.0.1:11234", adminBind->bytes); } // sanity check Assert_true(EventBase_eventCount(eventBase) == 0); // --------------------- Configuration ------------------------- // Configurator_config(&config, &adminAddr.addr, adminPass, eventBase, logger, allocator); return 0; }
int main(int argc, char** argv) { #ifdef Log_KEYS fprintf(stderr, "Log_LEVEL = KEYS, EXPECT TO SEE PRIVATE KEYS IN YOUR LOGS!\n"); #endif if (argc < 2) { // Fall through. } else if (!CString_strcmp("angel", argv[1])) { return AngelInit_main(argc, argv); } else if (!CString_strcmp("core", argv[1])) { return Core_main(argc, argv); } Assert_ifParanoid(argc > 0); struct Except* eh = NULL; // Allow it to allocate 8MB struct Allocator* allocator = MallocAllocator_new(1<<23); struct Random* rand = Random_new(allocator, NULL, eh); struct EventBase* eventBase = EventBase_new(allocator); if (argc == 2) { // one argument if ((CString_strcmp(argv[1], "--help") == 0) || (CString_strcmp(argv[1], "-h") == 0)) { return usage(allocator, argv[0]); } else if (CString_strcmp(argv[1], "--genconf") == 0) { return genconf(rand); } else if (CString_strcmp(argv[1], "--pidfile") == 0) { // deprecated fprintf(stderr, "'--pidfile' option is deprecated.\n"); return 0; } else if (CString_strcmp(argv[1], "--reconf") == 0) { // Performed after reading the configuration } else if (CString_strcmp(argv[1], "--bench") == 0) { return benchmark(); } else if ((CString_strcmp(argv[1], "--version") == 0) || (CString_strcmp(argv[1], "-v") == 0)) { printf("Cjdns protocol version: %d\n", Version_CURRENT_PROTOCOL); return 0; } else if (CString_strcmp(argv[1], "--cleanconf") == 0) { // Performed after reading configuration } else if (CString_strcmp(argv[1], "--nobg") == 0) { // Performed while reading configuration } else { fprintf(stderr, "%s: unrecognized option '%s'\n", argv[0], argv[1]); fprintf(stderr, "Try `%s --help' for more information.\n", argv[0]); return -1; } } else if (argc > 2) { // more than one argument? fprintf(stderr, "%s: too many arguments [%s]\n", argv[0], argv[1]); fprintf(stderr, "Try `%s --help' for more information.\n", argv[0]); // because of '--pidfile $filename'? if (CString_strcmp(argv[1], "--pidfile") == 0) { fprintf(stderr, "\n'--pidfile' option is deprecated.\n"); } return -1; } if (isatty(STDIN_FILENO)) { // We were started from a terminal // The chances an user wants to type in a configuration // bij hand are pretty slim so we show him the usage return usage(allocator, argv[0]); } else { // We assume stdin is a configuration file and that we should // start routing } struct Reader* stdinReader = FileReader_new(stdin, allocator); Dict config; if (JsonBencSerializer_get()->parseDictionary(stdinReader, allocator, &config)) { fprintf(stderr, "Failed to parse configuration.\n"); return -1; } if (argc == 2 && CString_strcmp(argv[1], "--cleanconf") == 0) { struct Writer* stdoutWriter = FileWriter_new(stdout, allocator); JsonBencSerializer_get()->serializeDictionary(stdoutWriter, &config); printf("\n"); return 0; } int forceNoBackground = 0; if (argc == 2 && CString_strcmp(argv[1], "--nobg") == 0) { forceNoBackground = 1; } struct Writer* logWriter = FileWriter_new(stdout, allocator); struct Log* logger = WriterLog_new(logWriter, allocator); // --------------------- Get Admin --------------------- // Dict* configAdmin = Dict_getDict(&config, String_CONST("admin")); String* adminPass = Dict_getString(configAdmin, String_CONST("password")); String* adminBind = Dict_getString(configAdmin, String_CONST("bind")); if (!adminPass) { adminPass = String_newBinary(NULL, 32, allocator); Random_base32(rand, (uint8_t*) adminPass->bytes, 32); adminPass->len = CString_strlen(adminPass->bytes); } if (!adminBind) { Except_throw(eh, "You must specify admin.bind in the cjdroute.conf file."); } // --------------------- Welcome to cjdns ---------------------- // char* archInfo = ArchInfo_describe(ArchInfo_detect(), allocator); char* sysInfo = SysInfo_describe(SysInfo_detect(), allocator); Log_info(logger, "Cjdns %s %s", archInfo, sysInfo); // --------------------- Check for running instance --------------------- // Log_info(logger, "Checking for running instance..."); checkRunningInstance(allocator, eventBase, adminBind, adminPass, logger, eh); // --------------------- Setup Pipes to Angel --------------------- // char angelPipeName[64] = "client-angel-"; Random_base32(rand, (uint8_t*)angelPipeName+13, 31); Assert_ifParanoid(EventBase_eventCount(eventBase) == 0); struct Pipe* angelPipe = Pipe_named(angelPipeName, eventBase, eh, allocator); Assert_ifParanoid(EventBase_eventCount(eventBase) == 2); angelPipe->logger = logger; char* args[] = { "angel", angelPipeName, NULL }; // --------------------- Spawn Angel --------------------- // String* privateKey = Dict_getString(&config, String_CONST("privateKey")); char* corePath = Process_getPath(allocator); if (!corePath) { Except_throw(eh, "Can't find a usable cjdns core executable, " "make sure it is in the same directory as cjdroute"); } if (!privateKey) { Except_throw(eh, "Need to specify privateKey."); } Log_info(logger, "Forking angel to background."); Process_spawn(corePath, args, eventBase, allocator); // --------------------- Get user for angel to setuid() ---------------------- // String* securityUser = NULL; List* securityConf = Dict_getList(&config, String_CONST("security")); for (int i = 0; securityConf && i < List_size(securityConf); i++) { securityUser = Dict_getString(List_getDict(securityConf, i), String_CONST("setuser")); if (securityUser) { int64_t* ea = Dict_getInt(List_getDict(securityConf, i), String_CONST("exemptAngel")); if (ea && *ea) { securityUser = NULL; } break; } } // --------------------- Pre-Configure Angel ------------------------- // Dict* preConf = Dict_new(allocator); Dict* adminPreConf = Dict_new(allocator); Dict_putDict(preConf, String_CONST("admin"), adminPreConf, allocator); Dict_putString(adminPreConf, String_CONST("core"), String_new(corePath, allocator), allocator); Dict_putString(preConf, String_CONST("privateKey"), privateKey, allocator); Dict_putString(adminPreConf, String_CONST("bind"), adminBind, allocator); Dict_putString(adminPreConf, String_CONST("pass"), adminPass, allocator); if (securityUser) { Dict_putString(adminPreConf, String_CONST("user"), securityUser, allocator); } Dict* logging = Dict_getDict(&config, String_CONST("logging")); if (logging) { Dict_putDict(preConf, String_CONST("logging"), logging, allocator); } struct Message* toAngelMsg = Message_new(0, 1024, allocator); BencMessageWriter_write(preConf, toAngelMsg, eh); Interface_sendMessage(&angelPipe->iface, toAngelMsg); Log_debug(logger, "Sent [%d] bytes to angel process", toAngelMsg->length); // --------------------- Get Response from Angel --------------------- // struct Message* fromAngelMsg = InterfaceWaiter_waitForData(&angelPipe->iface, eventBase, allocator, eh); Dict* responseFromAngel = BencMessageReader_read(fromAngelMsg, allocator, eh); // --------------------- Get Admin Addr/Port/Passwd --------------------- // Dict* responseFromAngelAdmin = Dict_getDict(responseFromAngel, String_CONST("admin")); adminBind = Dict_getString(responseFromAngelAdmin, String_CONST("bind")); if (!adminBind) { Except_throw(eh, "didn't get address and port back from angel"); } struct Sockaddr_storage adminAddr; if (Sockaddr_parse(adminBind->bytes, &adminAddr)) { Except_throw(eh, "Unable to parse [%s] as an ip address port, eg: 127.0.0.1:11234", adminBind->bytes); } // sanity check, Pipe_named() creates 2 events, see above. Assert_ifParanoid(EventBase_eventCount(eventBase) == 2); // --------------------- Configuration ------------------------- // Configurator_config(&config, &adminAddr.addr, adminPass, eventBase, logger, allocator); // --------------------- noBackground ------------------------ // int64_t* noBackground = Dict_getInt(&config, String_CONST("noBackground")); if (forceNoBackground || (noBackground && *noBackground)) { EventBase_beginLoop(eventBase); } //Allocator_free(allocator); return 0; }
int main(int argc, char** argv) { if (argc > 1 && !strcmp("--genconf", argv[argc-1])) { genconf(); return 0; } struct Allocator* alloc = MallocAllocator_new(1<<22); struct EventBase* base = EventBase_new(alloc); struct Writer* logWriter = FileWriter_new(stdout, alloc); struct Log* logger = WriterLog_new(logWriter, alloc); struct Random* rand = Random_new(alloc, logger, NULL); struct Reader* stdinReader = FileReader_new(stdin, alloc); Dict config; if (JsonBencSerializer_get()->parseDictionary(stdinReader, alloc, &config)) { Log_critical(logger, "Failed to parse configuration"); return -1; } Dict* dns = Dict_getDict(&config, String_CONST("dns")); if (!dns) { Log_critical(logger, "No DNS in configuration"); return -1; } struct Sockaddr_storage addr; Assert_true(!Sockaddr_parse("::", &addr)); struct AddrInterface* ifaceB = UDPAddrInterface_new(base, &addr.addr, alloc, NULL, logger); struct RainflyClient* client = RainflyClient_new(ifaceB, base, rand, logger); String* bind = Dict_getString(dns, String_CONST("bind")); Assert_true(!Sockaddr_parse(bind ? bind->bytes : "[::]:5353", &addr)); struct AddrInterface* iface = UDPAddrInterface_new(base, &addr.addr, alloc, NULL, logger); struct DNSServer* dnsServer = DNSServer_new(iface, logger, client); List* auth = Dict_getList(dns, String_CONST("authorities")); for (int i = 0; i < (int)List_size(auth); i++) { String* str = List_getString(auth, i); if (!str) { Log_warn(logger, "Element [%d] in [dns.authorities] list of wrong type", i); continue; } uint8_t key[32] = {0}; if (str->len < 52 || Base32_decode(key, 32, str->bytes, 52) != 32) { Log_warn(logger, "Failed to parse key [%s]", str->bytes); continue; } if (RainflyClient_addKey(client, key)) { Log_warn(logger, "Failed to add key to RainflyClient [%s]", str->bytes); } } List* servers = Dict_getList(dns, String_CONST("servers")); for (int i = 0; i < (int)List_size(servers); i++) { String* str = List_getString(servers, i); if (!str) { Log_warn(logger, "Element [%d] in [dns.servers] list of wrong type", i); continue; } struct Sockaddr_storage node; if (Sockaddr_parse(str->bytes, &node)) { Log_warn(logger, "Failed to parse server name [%s]", str->bytes); continue; } if (RainflyClient_addServer(client, &node.addr)) { Log_warn(logger, "Failed to add server to RainflyClient [%s]", str->bytes); } } List* legacy = Dict_getList(dns, String_CONST("legacy")); for (int i = 0; i < (int)List_size(legacy); i++) { String* str = List_getString(legacy, i); if (!str) { Log_warn(logger, "Element [%d] in [dns.legacy] list of wrong type", i); continue; } struct Sockaddr_storage node; if (Sockaddr_parse(str->bytes, &node)) { Log_warn(logger, "Failed to parse legacy server name [%s]", str->bytes); continue; } if (DNSServer_addServer(dnsServer, &node.addr)) { Log_warn(logger, "Failed to add server to DNSServer [%s]", str->bytes); } } EventBase_beginLoop(base); }
int main(int argc, char** argv) { #ifdef Log_KEYS fprintf(stderr, "Log_LEVEL = KEYS, EXPECT TO SEE PRIVATE KEYS IN YOUR LOGS!\n"); #endif Crypto_init(); Assert_true(argc > 0); if (argc == 2) { // one argument if (strcmp(argv[1], "--help") == 0) { return usage(argv[0]); } else if (strcmp(argv[1], "--genconf") == 0) { return genconf(); } else if (strcmp(argv[1], "--pidfile") == 0) { // Performed after reading the configuration } else if (strcmp(argv[1], "--reconf") == 0) { // Performed after reading the configuration } else if (strcmp(argv[1], "--bench") == 0) { return benchmark(); } else if (strcmp(argv[1], "--version") == 0) { printf("Version ID: %s\n", RouterModule_gitVersion()); return 0; } else { fprintf(stderr, "%s: unrecognized option '%s'\n", argv[0], argv[1]); fprintf(stderr, "Try `%s --help' for more information.\n", argv[0]); return -1; } } else if (argc > 2) { // more than one argument? fprintf(stderr, "%s: too many arguments\n", argv[0]); fprintf(stderr, "Try `%s --help' for more information.\n", argv[0]); return -1; } if (isatty(STDIN_FILENO)) { // We were started from a terminal // The chances an user wants to type in a configuration // bij hand are pretty slim so we show him the usage return usage(argv[0]); } else { // We assume stdin is a configuration file and that we should // start routing } struct event_base* eventBase = event_base_new(); // Allow it to allocate 4MB struct Allocator* allocator = MallocAllocator_new(1<<22); struct Reader* reader = FileReader_new(stdin, allocator); Dict config; if (JsonBencSerializer_get()->parseDictionary(reader, allocator, &config)) { fprintf(stderr, "Failed to parse configuration.\n"); return -1; } // Logging. struct Writer* logwriter = FileWriter_new(stdout, allocator); struct Log* logger = &(struct Log) { .writer = logwriter }; // pid file String* pidFile = Dict_getString(&config, String_CONST("pidFile")); if (pidFile) { if (argc == 2 && strcmp(argv[1], "--pidfile") == 0) { printf("%s", pidFile->bytes); return 0; } Log_info(logger, "Writing pid of process to [%s].\n", pidFile->bytes); FILE* pf = fopen(pidFile->bytes, "w"); if (!pf) { Log_critical(logger, "Failed to open pid file [%s] for writing, errno=%d\n", pidFile->bytes, errno); return -1; } fprintf(pf, "%d", (int) getpid()); fclose(pf); } // re-configure if (argc == 2 && strcmp(argv[1], "--reconf") == 0) { reconf(eventBase, &config, logger, allocator); return 0; } // ca, needed for admin. struct Address myAddr; uint8_t privateKey[32]; parsePrivateKey(&config, &myAddr, privateKey); struct CryptoAuth* cryptoAuth = CryptoAuth_new(&config, allocator, privateKey, eventBase, logger); // Admin char* user = setUser(Dict_getList(&config, String_CONST("security"))); struct Admin* admin = newAdmin(&config, user, logger, eventBase, allocator); struct SwitchCore* switchCore = SwitchCore_new(logger, allocator); struct DHTModuleRegistry* registry = DHTModuleRegistry_new(allocator); ReplyModule_register(registry, allocator); // Router struct Interface* routerIf = NULL; Dict* routerConf = Dict_getDict(&config, String_CONST("router")); Dict* iface = Dict_getDict(routerConf, String_CONST("interface")); if (String_equals(Dict_getString(iface, String_CONST("type")), String_CONST("TUNInterface"))) { String* ifName = Dict_getString(iface, String_CONST("tunDevice")); char assignedTunName[TUNConfigurator_IFNAMSIZ]; void* tunPtr = TUNConfigurator_initTun(((ifName) ? ifName->bytes : NULL), assignedTunName, logger, AbortHandler_INSTANCE); struct Jmp jmp; Jmp_try(jmp) { TUNConfigurator_setIpAddress( assignedTunName, myAddr.ip6.bytes, 8, logger, &jmp.handler); } Jmp_catch { Log_warn(logger, "Unable to configure ip address [%s]", jmp.message); } struct TUNInterface* tun = TUNInterface_new(tunPtr, eventBase, allocator); routerIf = &tun->iface; }