blob: a28f04df9cace076161883c55b8401e8123dfe5b [file] [log] [blame]
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001/*
2 *
Craig Tiller06059952015-02-18 08:34:56 -08003 * Copyright 2015, Google Inc.
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08004 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
34#include <grpc/support/host_port.h>
35
36#include <string.h>
37
Craig Tiller485d7762015-01-23 12:54:05 -080038#include "src/core/support/string.h"
Nicolas "Pixel" Noble589cba22015-02-20 22:58:54 -080039#include <grpc/support/alloc.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080040#include <grpc/support/log.h>
Masood Malekghassemi701af602015-06-03 15:01:17 -070041#include <grpc/support/string_util.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080042
43int gpr_join_host_port(char **out, const char *host, int port) {
44 if (host[0] != '[' && strchr(host, ':') != NULL) {
45 /* IPv6 literals must be enclosed in brackets. */
46 return gpr_asprintf(out, "[%s]:%d", host, port);
47 } else {
48 /* Ordinary non-bracketed host:port. */
49 return gpr_asprintf(out, "%s:%d", host, port);
50 }
Craig Tiller190d3602015-02-18 09:23:38 -080051}
Nicolas "Pixel" Noble589cba22015-02-20 22:58:54 -080052
Craig Tiller698d00c2015-07-20 12:32:58 -070053int gpr_split_host_port(const char *name, char **host, char **port) {
Nicolas "Pixel" Noble589cba22015-02-20 22:58:54 -080054 const char *host_start;
55 size_t host_len;
56 const char *port_start;
57
58 *host = NULL;
59 *port = NULL;
60
61 if (name[0] == '[') {
62 /* Parse a bracketed host, typically an IPv6 literal. */
63 const char *rbracket = strchr(name, ']');
64 if (rbracket == NULL) {
65 /* Unmatched [ */
Craig Tiller698d00c2015-07-20 12:32:58 -070066 return 0;
Nicolas "Pixel" Noble589cba22015-02-20 22:58:54 -080067 }
68 if (rbracket[1] == '\0') {
69 /* ]<end> */
70 port_start = NULL;
71 } else if (rbracket[1] == ':') {
72 /* ]:<port?> */
73 port_start = rbracket + 2;
74 } else {
75 /* ]<invalid> */
Craig Tiller698d00c2015-07-20 12:32:58 -070076 return 0;
Nicolas "Pixel" Noble589cba22015-02-20 22:58:54 -080077 }
78 host_start = name + 1;
murgatroid995e71d7a2015-06-19 12:24:44 -070079 host_len = (size_t)(rbracket - host_start);
Nicolas "Pixel" Noble589cba22015-02-20 22:58:54 -080080 if (memchr(host_start, ':', host_len) == NULL) {
81 /* Require all bracketed hosts to contain a colon, because a hostname or
82 IPv4 address should never use brackets. */
Craig Tiller698d00c2015-07-20 12:32:58 -070083 return 0;
Nicolas "Pixel" Noble589cba22015-02-20 22:58:54 -080084 }
85 } else {
86 const char *colon = strchr(name, ':');
87 if (colon != NULL && strchr(colon + 1, ':') == NULL) {
88 /* Exactly 1 colon. Split into host:port. */
89 host_start = name;
murgatroid995e71d7a2015-06-19 12:24:44 -070090 host_len = (size_t)(colon - name);
Nicolas "Pixel" Noble589cba22015-02-20 22:58:54 -080091 port_start = colon + 1;
92 } else {
93 /* 0 or 2+ colons. Bare hostname or IPv6 litearal. */
94 host_start = name;
95 host_len = strlen(name);
96 port_start = NULL;
97 }
98 }
99
100 /* Allocate return values. */
101 *host = gpr_malloc(host_len + 1);
102 memcpy(*host, host_start, host_len);
103 (*host)[host_len] = '\0';
104
105 if (port_start != NULL) {
106 *port = gpr_strdup(port_start);
107 }
Craig Tiller698d00c2015-07-20 12:32:58 -0700108
109 return 1;
Nicolas "Pixel" Noble589cba22015-02-20 22:58:54 -0800110}