-
-
Save cablehead/a634c26252611835cf1f0e1dc224e766 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <assert.h> | |
| #include <pthread.h> | |
| #include <unistd.h> | |
| #include <stdio.h> | |
| #include <sys/types.h> | |
| #include <sys/socket.h> | |
| #include <netdb.h> | |
| #include <string.h> | |
| #include <errno.h> | |
| int levee_dialer_fds[2]; | |
| int levee_dialer_rc; | |
| struct levee_dialer_request { | |
| uint16_t node_len; | |
| uint16_t service_len; | |
| int type; | |
| int no; | |
| }; | |
| struct levee_dialer_response { | |
| int err; | |
| int eai; | |
| int no; | |
| }; | |
| void * | |
| levee_dialer_loop(void *arg) { | |
| int rc; | |
| struct levee_dialer_request req; | |
| struct levee_dialer_response res; | |
| char node[8096]; | |
| char service[1024]; | |
| struct addrinfo hints, *info, *ptr; | |
| int no; | |
| int err; | |
| memset(&hints, 0, sizeof(hints)); | |
| hints.ai_family = AF_INET; | |
| hints.ai_socktype = SOCK_STREAM; | |
| while(1) { | |
| memset(&res, 0, sizeof(res)); | |
| rc = read(levee_dialer_fds[0], &req, sizeof(req)); | |
| assert(rc == sizeof(req)); | |
| rc = read(levee_dialer_fds[0], node, req.node_len); | |
| assert(rc == req.node_len); | |
| node[req.node_len] = 0; | |
| rc = read(levee_dialer_fds[0], service, req.service_len); | |
| assert(rc == req.service_len); | |
| service[req.service_len] = 0; | |
| rc = getaddrinfo(node, service, &hints, &info); | |
| if (rc != 0) { | |
| res.eai = rc; | |
| goto respond; | |
| } | |
| no = socket(PF_INET, req.type, 0); | |
| if (no < 0) { | |
| res.err = errno; | |
| goto respond; | |
| } | |
| for (ptr = info; ptr; ptr = ptr->ai_next) { | |
| rc = connect(no, ptr->ai_addr, ptr->ai_addrlen); | |
| if (rc == 0) break; | |
| err = errno; | |
| } | |
| freeaddrinfo(info); | |
| if (ptr == NULL) { | |
| res.err = err; | |
| } else { | |
| res.no = no; | |
| } | |
| respond: | |
| rc = write(req.no, &res, sizeof(res)); | |
| assert(rc == sizeof(res)); | |
| } | |
| } | |
| int levee_dialer_boot(void) { | |
| pthread_t thr; | |
| pthread_attr_t attr; | |
| int rc; | |
| rc = pipe(levee_dialer_fds); | |
| if (rc != 0) return rc; | |
| rc = pthread_attr_init (&attr); | |
| if (rc != 0) return rc; | |
| rc = pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); | |
| if (rc != 0) return rc; | |
| rc = pthread_create (&thr, &attr, &levee_dialer_loop, NULL); | |
| if (rc != 0) return rc; | |
| return 0; | |
| } | |
| pthread_once_t levee_dialer_once = PTHREAD_ONCE_INIT; | |
| void levee_dialer_run_once(void) { | |
| levee_dialer_rc = levee_dialer_boot(); | |
| } | |
| void levee_dialer_init(void) { | |
| pthread_once(&levee_dialer_once, levee_dialer_run_once); | |
| } | |
| int | |
| writer(const char *node, const char *service) { | |
| int rc; | |
| struct levee_dialer_request req; | |
| struct levee_dialer_response res; | |
| int fds[2]; | |
| rc = pipe(fds); | |
| if (rc != 0) return rc; | |
| req.node_len = (uint16_t) strlen(node); | |
| req.service_len = (uint16_t) strlen(service); | |
| req.type = SOCK_STREAM; | |
| req.no = fds[1]; | |
| rc = write(levee_dialer_fds[1], &req, sizeof(req)); | |
| assert(rc == sizeof(req)); | |
| rc = write(levee_dialer_fds[1], node, strlen(node)); | |
| assert(rc == strlen(node)); | |
| rc = write(levee_dialer_fds[1], service, strlen(service)); | |
| assert(rc == strlen(service)); | |
| rc = read(fds[0], &res, sizeof(res)); | |
| assert(rc == sizeof(res)); | |
| printf("%s \\ %s \\ %d\n", gai_strerror(res.eai), strerror(res.err), res.no); | |
| return 0; | |
| } | |
| int main(int argc, char **argv) | |
| { | |
| levee_dialer_init(); | |
| writer("localhost", "8000"); | |
| writer("localhost", "8080"); | |
| writer("ldld", "8080"); | |
| return 0; | |
| } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment