1 /* $OpenBSD: unixsock_test.c,v 1.2 2021/12/15 20:41:28 bluhm Exp $ */ 2 /* Written by Claudio Jeker in 2011 */ 3 /* Public domain */ 4 #include <sys/types.h> 5 #include <sys/socket.h> 6 #include <sys/stat.h> 7 #include <sys/un.h> 8 #include <sys/wait.h> 9 #include <err.h> 10 #include <string.h> 11 #include <unistd.h> 12 #include <stdlib.h> 13 #include <stdio.h> 14 #include <errno.h> 15 16 char path[1024]; 17 char *dir; 18 19 static int 20 test_bind(struct sockaddr_un *sun, socklen_t slen) 21 { 22 int s, e, r; 23 24 s = socket(AF_UNIX, SOCK_STREAM, 0); 25 if (s == -1) 26 err(1, "socket"); 27 28 r = bind(s, (struct sockaddr *)sun, slen); 29 e = errno; 30 close(s); 31 sun->sun_path[slen - 2] = '\0'; 32 unlink(sun->sun_path); 33 errno = e; 34 return r; 35 } 36 37 static int 38 test_connect(struct sockaddr_un *sun, socklen_t slen, struct sockaddr_un *b) 39 { 40 int s, s2, e, r; 41 42 s = socket(AF_UNIX, SOCK_STREAM, 0); 43 if (s == -1) 44 err(1, "socket"); 45 46 s2 = socket(AF_UNIX, SOCK_STREAM, 0); 47 if (s2 == -1) 48 err(1, "socket"); 49 if (bind(s2, (struct sockaddr *)b, sizeof(*b)) == -1) 50 err(1, "bind"); 51 if (listen(s2, 5) == -1) 52 err(1, "listen"); 53 54 r = connect(s, (struct sockaddr *)sun, slen); 55 e = errno; 56 close(s); 57 close(s2); 58 unlink(b->sun_path); 59 errno = e; 60 return r; 61 } 62 63 struct test { 64 socklen_t len; 65 int r; 66 } t[] = { 67 {30, 0}, 68 {50, 0}, 69 {100, 0}, 70 {102, 0}, 71 {103, 0}, 72 {104, -1}, 73 {105, -1}, 74 {110, -1}, 75 {200, -1}, 76 {0, 0} 77 }; 78 79 int 80 main() 81 { 82 struct sockaddr_storage ss; 83 struct sockaddr_un *sun, sun2; 84 char dir_template[] = "/tmp/peer.XXXXXXXXXX"; 85 char aaa[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 86 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 87 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; 88 int i, fail = 0; 89 90 dir = mkdtemp(dir_template); 91 if (!dir) 92 err(1, "mkdtemp"); 93 if (chdir(dir) == -1) 94 err(1, "chdir"); 95 snprintf(path, sizeof path, "%s/%s", dir, "socket"); 96 97 for (i = 0; t[i].len != 0; i++) { 98 socklen_t slen = t[i].len; 99 memset(&ss, 0xfe, sizeof(ss)); 100 sun = (struct sockaddr_un *)&ss; 101 sun->sun_family = AF_UNIX; 102 103 memset(&sun2, 0, sizeof(sun2)); 104 sun2.sun_family = AF_UNIX; 105 106 snprintf(sun->sun_path, sizeof(ss) - 2, "%s.%.*s", path, 107 (int)(slen - strlen(path) - 1), aaa); 108 snprintf(sun2.sun_path, sizeof(sun2) - 2, "%s.%.*s", "socket", 109 (int)(slen - strlen(path) - 1), aaa); 110 111 if (test_bind(sun, slen + 2) != t[i].r) { 112 warn("FAIL: bind(\"%s\") len %d", sun->sun_path, 113 slen + 2); 114 fail = 1; 115 } 116 if (test_bind(sun, slen + 3) != t[i].r) { 117 warn("FAIL2: bind(\"%s\") len %d", sun->sun_path, 118 slen + 3); 119 fail = 1; 120 } 121 if (sizeof(*sun) >= slen + 2 && 122 test_bind(sun, sizeof(*sun)) != t[i].r) { 123 warn("FAIL3: bind(\"%s\") len %zd", sun->sun_path, 124 sizeof(*sun)); 125 fail = 1; 126 } 127 sun->sun_path[slen] = 'a'; 128 if (test_bind(sun, slen + 2) != t[i].r) { 129 warn("FAIL4: bind(\"%.*s\") len %d no-NUL", 130 (int)(slen + 2), sun->sun_path, slen + 2); 131 fail = 1; 132 } 133 sun->sun_path[slen] = '\0'; 134 135 if (test_connect(sun, slen + 2, &sun2) != t[i].r) { 136 warn("FAIL: connect(\"%s\") len %d", sun->sun_path, 137 slen + 2); 138 fail = 1; 139 } 140 if (test_connect(sun, slen + 3, &sun2) != t[i].r) { 141 warn("FAIL2: connect(\"%s\") len %d", sun->sun_path, 142 slen + 3); 143 fail = 1; 144 } 145 if (sizeof(*sun) >= slen + 2 && 146 test_connect(sun, sizeof(*sun), &sun2) != t[i].r) { 147 warn("FAIL3: connect(\"%s\") len %zd", sun->sun_path, 148 sizeof(*sun)); 149 fail = 1; 150 } 151 sun->sun_path[slen] = 'a'; 152 if (test_connect(sun, slen + 2, &sun2) != t[i].r) { 153 warn("FAIL4: connect(\"%.*s\") len %d no-NUL", 154 slen + 2, sun->sun_path, slen + 2); 155 fail = 1; 156 } 157 } 158 return fail; 159 } 160