cmi_status_t cmj_resolve_nod_tnd(cmi_descriptor *nod, cmi_descriptor *tnd, struct sockaddr_in *inp) { cmi_status_t status = SS_NORMAL; char hn[MAX_HOST_NAME_LEN]; struct hostent *hp; int loop_limit = MAX_GETHOST_TRIES; /* tnd may contain host:port */ status = cmj_getsockaddr(tnd, inp); if (CMI_ERROR(status)) return status; if (inp->sin_addr.s_addr == INADDR_ANY) { /* use nod as a host name if tnd was just a port */ assert(CMI_DESC_LENGTH(nod) < (SIZEOF(hn)-1)); memcpy(hn, CMI_DESC_POINTER(nod), CMI_DESC_LENGTH(nod)); hn[CMI_DESC_LENGTH(nod)] = '\0'; /* test to see if nod is a dotted quad text string */ inp->sin_addr.s_addr = INET_ADDR(hn); if (inp->sin_addr.s_addr == (in_addr_t)-1) { /* assume hn is a host and query netdb */ for (; 0 < loop_limit && (NULL == (hp = GETHOSTBYNAME(hn))) && TRY_AGAIN == h_errno; loop_limit--) ; endhostent(); if (!hp) return CMI_NETFAIL; inp->sin_addr = *(struct in_addr *)hp->h_addr; } } return status; }
struct CLB *cmu_getclb(cmi_descriptor *node, cmi_descriptor *task) { cmi_status_t status; struct CLB *p; que_ent_ptr_t qp; sigset_t oset; struct addrinfo *ai_ptr; int rc; status = cmj_getsockaddr(node, task, &ai_ptr); if (CMI_ERROR(status)) return NULL; if (ntd_root) { SIGPROCMASK(SIG_BLOCK, &ntd_root->mutex_set, &oset, rc); for (qp = RELQUE2PTR(ntd_root->cqh.fl) ; qp != &ntd_root->cqh ; qp = RELQUE2PTR(p->cqe.fl)) { p = QUEENT2CLB(qp, cqe); if (0 == memcpy(ai_ptr->ai_addr, (sockaddr_ptr)(&p->peer_sas), ai_ptr->ai_addrlen)) { SIGPROCMASK(SIG_SETMASK, &oset, NULL, rc); return p; } } SIGPROCMASK(SIG_SETMASK, &oset, NULL, rc); } return NULL; }
cmi_status_t cmi_init(cmi_descriptor *tnd, unsigned char tnr, void (*err)(struct NTD *, struct CLB *, cmi_reason_t reason), void (*crq)(struct CLB *), bool (*acc)(struct CLB *), void (*urg)(struct CLB *, unsigned char data), size_t pool_size, size_t usr_size, size_t mbl) { cmi_status_t status = SS_NORMAL; char *envvar; struct protoent *p; unsigned short myport; struct sockaddr_in in; sigset_t oset; int on = 1; int rval, rc, save_errno; status = cmj_netinit(); if (CMI_ERROR(status)) return status; status = cmj_getsockaddr(tnd, &in); if (CMI_ERROR(status)) return status; ntd_root->pool_size = pool_size; ntd_root->usr_size = usr_size; ntd_root->mbl = mbl; p = getprotobyname(GTCM_SERVER_PROTOCOL); endprotoent(); if (!p) return CMI_NETFAIL; /* create the listening socket */ ntd_root->listen_fd = socket(AF_INET, SOCK_STREAM, p->p_proto); if (FD_INVALID == ntd_root->listen_fd) return errno; /* make sure we can re-run quickly w/o reuse problems */ status = setsockopt(ntd_root->listen_fd, SOL_SOCKET, SO_REUSEADDR, (void*)&on, SIZEOF(on)); if (-1 == status) { save_errno = errno; CLOSEFILE_RESET(ntd_root->listen_fd, rc); /* resets "ntd_root->listen_fd" to FD_INVALID */ return save_errno; } status = bind(ntd_root->listen_fd, (struct sockaddr*)&in, SIZEOF(in)); if (-1 == status) { save_errno = errno; CLOSEFILE_RESET(ntd_root->listen_fd, rc); /* resets "ntd_root->listen_fd" to FD_INVALID */ return save_errno; } status = cmj_setupfd(ntd_root->listen_fd); if (CMI_ERROR(status)) { CLOSEFILE_RESET(ntd_root->listen_fd, rc); /* resets "ntd_root->listen_fd" to FD_INVALID */ return status; } SIGPROCMASK(SIG_BLOCK, &ntd_root->mutex_set, &oset, rc); rval = listen(ntd_root->listen_fd, MAX_CONN_IND); if (-1 == rval) { save_errno = errno; CLOSEFILE_RESET(ntd_root->listen_fd, rc); /* resets "ntd_root->listen_fd" to FD_INVALID */ SIGPROCMASK(SIG_SETMASK, &oset, NULL, rc); return save_errno; } status = cmj_set_async(ntd_root->listen_fd); if (CMI_ERROR(status)) { CLOSEFILE_RESET(ntd_root->listen_fd, rc); /* resets "ntd_root->listen_fd" to FD_INVALID */ SIGPROCMASK(SIG_SETMASK, &oset, NULL, rc); return status; } FD_SET(ntd_root->listen_fd, &ntd_root->rs); FD_SET(ntd_root->listen_fd, &ntd_root->es); ntd_root->err = err; ntd_root->crq = crq; ntd_root->acc = acc; ntd_root->urg = urg; if (ntd_root->listen_fd > ntd_root->max_fd) ntd_root->max_fd = ntd_root->listen_fd; cmj_housekeeping(); /* will establish listening pools */ SIGPROCMASK(SIG_SETMASK, &oset, NULL, rc); return SS_NORMAL; }