[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] libgpsd_core: handle IPv6 literals in devices' URIs
From: |
Paul Fertser |
Subject: |
[PATCH] libgpsd_core: handle IPv6 literals in devices' URIs |
Date: |
Sat, 21 Dec 2019 01:05:53 +0300 |
When handling URIs for connecting to remote devices, honour RFC3986
rules for parsing IPv6 (or later) literals (enclosed within square
brackets).
Fixes #44.
---
libgpsd_core.c | 65 ++++++++++++++++++++++++++++++++++----------------
1 file changed, 45 insertions(+), 20 deletions(-)
diff --git a/libgpsd_core.c b/libgpsd_core.c
index 7adbb1793..52bf8e5ae 100644
--- a/libgpsd_core.c
+++ b/libgpsd_core.c
@@ -422,6 +422,35 @@ void gpsd_clear(struct gps_device_t *session)
session->opentime = time(NULL);
}
+static int parse_uri_dest(struct gps_device_t *session, char *s,
+ char **host, char **service)
+/* split s into host and service parts
+ * if service is not specified, *service is assigned to NULL
+ * return: -1 on error, 0 otherwise
+ */
+{
+ if (s[0] != '[') {
+ *host = s;
+ s = strchr(s, ':');
+ } else { /* IPv6 literal */
+ char *cb = strchr(s, ']');
+ if (!cb || (cb[1] && cb[1] != ':')) {
+ GPSD_LOG(LOG_ERROR, &session->context->errout,
+ "Malformed URI specified.\n");
+ return -1;
+ }
+ *cb = '\0';
+ *host = s + 1;
+ s = cb + 1;
+ }
+ if (s && s[0] && s[1]) {
+ *s = '\0';
+ *service = s + 1;
+ } else
+ *service = NULL;
+ return 0;
+}
+
int gpsd_open(struct gps_device_t *session)
/* open a device for access to its data *
* return: the opened file descriptor
@@ -442,21 +471,19 @@ int gpsd_open(struct gps_device_t *session)
return session->gpsdata.gps_fd;
/* otherwise, could be an TCP data feed */
} else if (str_starts_with(session->gpsdata.dev.path, "tcp://")) {
- char server[GPS_PATH_MAX], *port;
+ char server[GPS_PATH_MAX], *host, *port;
socket_t dsock;
(void)strlcpy(server, session->gpsdata.dev.path + 6, sizeof(server));
INVALIDATE_SOCKET(session->gpsdata.gps_fd);
- port = strchr(server, ':');
- if (port == NULL) {
+ if (parse_uri_dest(session, server, &host, &port) == -1 || !port) {
GPSD_LOG(LOG_ERROR, &session->context->errout,
- "Missing colon in TCP feed spec.\n");
+ "Missing service in TCP feed spec.\n");
return -1;
}
- *port++ = '\0';
GPSD_LOG(LOG_INF, &session->context->errout,
- "opening TCP feed at %s, port %s.\n", server,
+ "opening TCP feed at %s, port %s.\n", host,
port);
- if ((dsock = netlib_connectsock(AF_UNSPEC, server, port, "tcp")) < 0) {
+ if ((dsock = netlib_connectsock(AF_UNSPEC, host, port, "tcp")) < 0) {
GPSD_LOG(LOG_ERROR, &session->context->errout,
"TCP device open error %s.\n",
netlib_errstr(dsock));
@@ -469,21 +496,19 @@ int gpsd_open(struct gps_device_t *session)
return session->gpsdata.gps_fd;
/* or could be UDP */
} else if (str_starts_with(session->gpsdata.dev.path, "udp://")) {
- char server[GPS_PATH_MAX], *port;
+ char server[GPS_PATH_MAX], *host, *port;
socket_t dsock;
(void)strlcpy(server, session->gpsdata.dev.path + 6, sizeof(server));
INVALIDATE_SOCKET(session->gpsdata.gps_fd);
- port = strchr(server, ':');
- if (port == NULL) {
+ if (parse_uri_dest(session, server, &host, &port) == -1 || !port) {
GPSD_LOG(LOG_ERROR, &session->context->errout,
- "Missing colon in UDP feed spec.\n");
+ "Missing service in UDP feed spec.\n");
return -1;
}
- *port++ = '\0';
GPSD_LOG(LOG_INF, &session->context->errout,
- "opening UDP feed at %s, port %s.\n", server,
+ "opening UDP feed at %s, port %s.\n", host,
port);
- if ((dsock = netlib_connectsock(AF_UNSPEC, server, port, "udp")) < 0) {
+ if ((dsock = netlib_connectsock(AF_UNSPEC, host, port, "udp")) < 0) {
GPSD_LOG(LOG_ERROR, &session->context->errout,
"UDP device open error %s.\n",
netlib_errstr(dsock));
@@ -498,18 +523,18 @@ int gpsd_open(struct gps_device_t *session)
#endif /* NETFEED_ENABLE */
#ifdef PASSTHROUGH_ENABLE
if (str_starts_with(session->gpsdata.dev.path, "gpsd://")) {
- char server[GPS_PATH_MAX], *port;
+ char server[GPS_PATH_MAX], *host, *port;
socket_t dsock;
(void)strlcpy(server, session->gpsdata.dev.path + 7, sizeof(server));
INVALIDATE_SOCKET(session->gpsdata.gps_fd);
- if ((port = strchr(server, ':')) == NULL) {
+ if (parse_uri_dest(session, server, &host, &port) == -1)
+ return -1;
+ if (!port)
port = DEFAULT_GPSD_PORT;
- } else
- *port++ = '\0';
GPSD_LOG(LOG_INF, &session->context->errout,
"opening remote gpsd feed at %s, port %s.\n",
- server, port);
- if ((dsock = netlib_connectsock(AF_UNSPEC, server, port, "tcp")) < 0) {
+ host, port);
+ if ((dsock = netlib_connectsock(AF_UNSPEC, host, port, "tcp")) < 0) {
GPSD_LOG(LOG_ERROR, &session->context->errout,
"remote gpsd device open error %s.\n",
netlib_errstr(dsock));
--
2.24.1
- [PATCH] libgpsd_core: handle IPv6 literals in devices' URIs,
Paul Fertser <=
- Re: [PATCH] libgpsd_core: handle IPv6 literals in devices' URIs, Gary E. Miller, 2019/12/20
- warning of rushed release!, Greg Troxel, 2019/12/20
- Re: warning of rushed release!, Gary E. Miller, 2019/12/20
- Re: all I want for Xmas, rutled31, 2019/12/21
- Re: all I want for Xmas, Gary E. Miller, 2019/12/21
- Re: all I want for Xmas, rutled31, 2019/12/22
- Re: all I want for Xmas, Gary E. Miller, 2019/12/22
- Re: all I want for Xmas, rutled31, 2019/12/23
- Re: all I want for Xmas, Norton Allen, 2019/12/24
- Re: all I want for Xmas, Bernd Zeimetz, 2019/12/23