static int c_lo_connect(u_sourceinfo *si, u_msg *msg) { u_link_block *block; int port; int af; struct sockaddr_storage addr; socklen_t addrlen = sizeof(addr); /* TODO: remote version */ if (!(block = u_find_link(msg->argv[0]))) { notice(si->u, "connect: host %s not in config", msg->argv[0]); return 0; } port = block->port; if (msg->argc > 1) { port = atoi(msg->argv[1]); if (port <= 0 || port >= 65536) { port = block->port; notice(si->u, "connect: %s: invalid port number; " "using %d in config", msg->argv[1], port); } } u_pton(block->host, &addr); switch (addr.ss_family) { case AF_INET6: ((struct sockaddr_in*) &addr)->sin_port = htons(port); break; case AF_INET: ((struct sockaddr_in6*)&addr)->sin6_port = htons(port); break; default: notice(si->u, "connect: could not make host %s in config " "into an address", block->host); return 0; } u_link_connect(base_ev, block, (struct sockaddr*)&addr, addrlen); return 0; }
u_link *u_link_from_json(mowgli_json_t *jl) { u_link *link; mowgli_json_t *jcookie, *jconn; mowgli_string_t *jpass, *jslinkname; ssize_t sz; link = link_create(); if (json_ogetu(jl, "flags", &link->flags) < 0) goto error; if (json_ogetu(jl, "type", &link->type) < 0) goto error; if (json_ogeti(jl, "sendq", &link->sendq) < 0) goto error; if ((sz = json_ogetb64(jl, "ibuf", link->ibuf, IBUFSIZE)) < 0) goto error; link->ibuflen = sz; link->ibuf[link->ibuflen] = '\0'; jpass = json_ogets(jl, "pass"); if (jpass) { link->pass = malloc(jpass->pos+1); memcpy(link->pass, jpass->str, jpass->pos); link->pass[jpass->pos] = '\0'; } jcookie = json_ogeto(jl, "ck_sendto"); if (!jcookie) goto error; if (u_cookie_from_json(jcookie, &link->ck_sendto) < 0) goto error; jconn = json_ogeto(jl, "conn"); if (!jconn) goto error; link->conn = u_conn_from_json(base_ev, &u_link_conn_ctx, link, jconn); if (!link->conn) goto error; link->conn->priv = link; /* This must run after the config has been loaded. */ switch (link->type) { case LINK_USER: /* If the user is post-registration, re-find his auth block. */ if (link->flags & U_LINK_REGISTERED) { /* XXX: Should this be in user.c? */ link->conf.auth = u_find_auth(link); if (!link->conf.auth) goto error; } break; case LINK_SERVER: jslinkname = json_ogets(jl, "server_link_block_name"); if (!jslinkname) goto error; /* mowgli_string is NULL-terminated. We needn't care about NULLs. */ link->conf.link = u_find_link(jslinkname->str); if (!link->conf.link) goto error; break; default: u_log(LG_SEVERE, "unexpected link type %d", link->type); abort(); } return link; error: if (link) { free(link->pass); free(link); } return NULL; }