aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLorenzo Colitti <lorenzo@google.com>2014-05-30 23:39:50 +0900
committerLorenzo Colitti <lorenzo@google.com>2014-06-17 14:04:29 +0900
commit3d667ccb6c8aa805006cfbe2bc793a4ee1ae0047 (patch)
treed1205ba8d73113c5ddd6d475c5ef7661534affa2
parent44a65406c9d97908145fd03deeaf531f4645ad6f (diff)
downloadiputils-3d667ccb6c8aa805006cfbe2bc793a4ee1ae0047.tar.gz
Make ping use socket marks properly.
ping and ping6 have an option to set the socket mark on the sockets they use, but unfortunately they do not use that option on the sockets they use to determine their local address. Thus, those checks are incorrect, and can result in ping failing to run if unmarked sockets have no connectivity. Change-Id: I2b8c30d314d6723a89d26d636f4f3fd0b9b8c3ac
-rw-r--r--ping.c3
-rw-r--r--ping6.c3
-rw-r--r--ping_common.c35
-rw-r--r--ping_common.h1
4 files changed, 27 insertions, 15 deletions
diff --git a/ping.c b/ping.c
index 23613c8..ec4e040 100644
--- a/ping.c
+++ b/ping.c
@@ -360,6 +360,9 @@ main(int argc, char **argv)
dst.sin_port = htons(1025);
if (nroute)
dst.sin_addr.s_addr = route[0];
+
+ sock_setmark(probe_fd);
+
if (connect(probe_fd, (struct sockaddr*)&dst, sizeof(dst)) == -1) {
if (errno == EACCES) {
if (broadcast_pings == 0) {
diff --git a/ping6.c b/ping6.c
index 2f8dddc..baa0768 100644
--- a/ping6.c
+++ b/ping6.c
@@ -988,6 +988,9 @@ int main(int argc, char *argv[])
disable_capability_raw();
}
firsthop.sin6_port = htons(1025);
+
+ sock_setmark(probe_fd);
+
if (connect(probe_fd, (struct sockaddr*)&firsthop, sizeof(firsthop)) == -1) {
perror("connect");
exit(2);
diff --git a/ping_common.c b/ping_common.c
index 9c0e8f5..d58d3c4 100644
--- a/ping_common.c
+++ b/ping_common.c
@@ -605,6 +605,25 @@ void sock_setbufs(int icmp_sock, int alloc)
}
}
+void sock_setmark(int icmp_sock) {
+#ifdef SO_MARK
+ if (options & F_MARK) {
+ int ret;
+
+ enable_capability_admin();
+ ret = setsockopt(icmp_sock, SOL_SOCKET, SO_MARK, &mark, sizeof(mark));
+ disable_capability_admin();
+
+ if (ret == -1) {
+ /* we probably dont wanna exit since old kernels
+ * dont support mark ..
+ */
+ fprintf(stderr, "Warning: Failed to set mark %d\n", mark);
+ }
+ }
+#endif
+}
+
/* Protocol independent setup and parameter checks. */
void setup(int icmp_sock)
@@ -639,22 +658,8 @@ void setup(int icmp_sock)
fprintf(stderr, "Warning: no SO_TIMESTAMP support, falling back to SIOCGSTAMP\n");
}
#endif
-#ifdef SO_MARK
- if (options & F_MARK) {
- int ret;
-
- enable_capability_admin();
- ret = setsockopt(icmp_sock, SOL_SOCKET, SO_MARK, &mark, sizeof(mark));
- disable_capability_admin();
- if (ret == -1) {
- /* we probably dont wanna exit since old kernels
- * dont support mark ..
- */
- fprintf(stderr, "Warning: Failed to set mark %d\n", mark);
- }
- }
-#endif
+ sock_setmark(icmp_sock);
/* Set some SNDTIMEO to prevent blocking forever
* on sends, when device is too slow or stalls. Just put limit
diff --git a/ping_common.h b/ping_common.h
index bc59700..7158555 100644
--- a/ping_common.h
+++ b/ping_common.h
@@ -284,6 +284,7 @@ extern int is_ours(uint16_t id);
extern int pinger(void);
extern void sock_setbufs(int icmp_sock, int alloc);
+extern void sock_setmark(int icmp_sock);
extern void setup(int icmp_sock);
extern void main_loop(int icmp_sock, __u8 *buf, int buflen) __attribute__((noreturn));
extern void finish(void) __attribute__((noreturn));