From e4aad1bc7ebe7a9e276d40dec80de41240b279a5 Mon Sep 17 00:00:00 2001 From: Gao feng Date: Thu, 30 Mar 2017 22:26:21 +0800 Subject: [PATCH] support dns search & options Signed-off-by: Gao feng --- src/hyper.h | 4 ++++ src/net.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++--- src/parse.c | 44 ++++++++++++++++++++++--------------- 3 files changed, 90 insertions(+), 20 deletions(-) diff --git a/src/hyper.h b/src/hyper.h index eed7c41b..71470d62 100644 --- a/src/hyper.h +++ b/src/hyper.h @@ -23,6 +23,8 @@ struct hyper_pod { struct hyper_route *rt; struct portmapping_white_list *portmap_white_lists; char **dns; + char **dns_search; + char **dns_option; struct list_head containers; struct list_head exec_head; char *hostname; @@ -31,6 +33,8 @@ struct hyper_pod { uint32_t i_num; uint32_t r_num; uint32_t d_num; + uint32_t dsearch_num; + uint32_t doption_num; /* how many containers are running */ uint32_t remains; int req_destroy; diff --git a/src/net.c b/src/net.c index b5eed6ae..a66a3422 100644 --- a/src/net.c +++ b/src/net.c @@ -677,10 +677,61 @@ int hyper_cmd_setup_route(char *json, int length) { return ret; } +int hyper_write_dns_file(int fd, char *field, char **data, int num) +{ + int i = 0, len = 0, ret = -1, size; + char *buf = NULL; + + if (num == 0) + return 0; + + size = strlen(field); + buf = malloc(size); + if (buf == NULL) { + fprintf(stderr, "fail to malloc buff for %s\n", field); + goto out; + } + memcpy(buf, field, size); + for (i = 0; i < num; i++) { + int new_len = strlen(data[i]) + 1 + 1; + char *format = " %s"; + if (i + 1 == num) { + new_len += 1; + format = " %s\n"; + } + buf = realloc(buf, size + new_len); + if (buf == NULL) { + fprintf(stderr, "fail to realloc buff for %s\n", field); + goto out; + } + if (snprintf(buf + size, new_len, format, data[i]) < 0) { + fprintf(stderr, "sprintf search entry failed\n"); + goto out; + } + fprintf(stdout, "%s: data: %s\n", field, buf); + size += new_len; + } + + while (len < size) { + i = write(fd, buf + len, size - len); + if (i < 0) { + perror("fail to write resolv.conf"); + goto out; + } + len += i; + } + + ret = 0; +out: + free(buf); + return ret; +} + int hyper_setup_dns(struct hyper_pod *pod) { int i, fd, ret = -1; char buf[28]; + int len = 0, size = 0; if (pod->dns == NULL) return 0; @@ -693,9 +744,9 @@ int hyper_setup_dns(struct hyper_pod *pod) } for (i = 0; i < pod->d_num; i++) { - int size = snprintf(buf, sizeof(buf), "nameserver %s\n", pod->dns[i]); - int len = 0, l; - + int l; + len = 0; + size = snprintf(buf, sizeof(buf), "nameserver %s\n", pod->dns[i]); if (size < 0) { fprintf(stderr, "sprintf resolv.conf entry failed\n"); goto out; @@ -711,6 +762,11 @@ int hyper_setup_dns(struct hyper_pod *pod) } } + if (hyper_write_dns_file(fd, "search", pod->dns_search, pod->dsearch_num) < 0 || + hyper_write_dns_file(fd, "options", pod->dns_option, pod->doption_num) < 0) { + goto out; + } + ret = 0; out: close(fd); diff --git a/src/parse.c b/src/parse.c index e567886f..4621271b 100644 --- a/src/parse.c +++ b/src/parse.c @@ -1060,30 +1060,33 @@ int hyper_parse_setup_routes(struct hyper_route **routes, uint32_t *r_num, char return ret; } -static int hyper_parse_dns(struct hyper_pod *pod, char *json, jsmntok_t *toks) +static int hyper_parse_string_array(char *json, jsmntok_t *toks, char *field, + char ***data, unsigned int *num) { int i = 0, j; + char **values; if (toks[i].type != JSMN_ARRAY) { - dbg_pr(stdout, "Dns format incorrect\n"); + dbg_pr(stdout, "%s format incorrect\n", field); return -1; } - pod->d_num = toks[i].size; - dbg_pr(stdout, "dns count %d\n", pod->d_num); + *num = toks[i].size; + dbg_pr(stdout, "%s count %d\n", field, *num); - pod->dns = calloc(pod->d_num, sizeof(*pod->dns)); - if (pod->dns == NULL) { - dbg_pr(stdout, "alloc memory for dns failed\n"); + values = calloc(*num, sizeof(*values)); + if (data == NULL) { + dbg_pr(stdout, "alloc memory for %s failed\n", field); return -1; } i++; - for (j = 0; j < pod->d_num; j++, i++) { - pod->dns[j] = json_token_str(json, &toks[i]); - dbg_pr(stdout, "pod dns %d: %s\n", j, pod->dns[j]); + for (j = 0; j < *num; j++, i++) { + values[j] = json_token_str(json, &toks[i]); + dbg_pr(stdout, "%s option %d: %s\n", field, j, values[j]); } + *data = values; return i; } @@ -1247,25 +1250,34 @@ int hyper_parse_pod(struct hyper_pod *pod, char *json, int length) next = hyper_parse_containers(pod, json, &toks[++i]); if (next < 0) goto out; - i += next; } else if (json_token_streq(json, t, "interfaces") && t->size == 1) { next = hyper_parse_interfaces(pod, json, &toks[++i]); if (next < 0) goto out; - i += next; } else if (json_token_streq(json, t, "routes") && t->size == 1) { next = hyper_parse_routes(&pod->rt, &pod->r_num, json, &toks[++i]); if (next < 0) goto out; - i += next; } else if (json_token_streq(json, t, "dns") && t->size == 1) { - next = hyper_parse_dns(pod, json, &toks[++i]); + next = hyper_parse_string_array(json, &toks[++i], "dns", + &pod->dns, &pod->d_num); + if (next < 0) + goto out; + i += next; + } else if (json_token_streq(json, t, "dnsSearch") && t->size == 1) { + next = hyper_parse_string_array(json, &toks[++i], "dns search", + &pod->dns_search, &pod->dsearch_num); + if (next < 0) + goto out; + i += next; + } else if (json_token_streq(json, t, "dnsOptions") && t->size == 1) { + next = hyper_parse_string_array(json, &toks[++i], "dns option", + &pod->dns_option, &pod->doption_num); if (next < 0) goto out; - i += next; } else if (json_token_streq(json, t, "shareDir") && t->size == 1) { pod->share_tag = (json_token_str(json, &toks[++i])); @@ -1282,7 +1294,6 @@ int hyper_parse_pod(struct hyper_pod *pod, char *json, int length) next = hyper_parse_portmapping_whitelist(pod, json, &toks[++i]); if (next < 0) goto out; - i += next; } else { hyper_print_unknown_key(json, &toks[i]); @@ -1290,7 +1301,6 @@ int hyper_parse_pod(struct hyper_pod *pod, char *json, int length) break; } } - out: free(toks); return next;