comparison src/common.c @ 15:1fa5b5fa49e1 V2.1.5

Fixed a race condition caused by reception of ICMP errors
author Ivo Smits <Ivo@UCIS.nl>
date Sun, 13 Feb 2011 23:56:54 +0100
parents f7e0145d8e2a
children 38d495566d1c
comparison
equal deleted inserted replaced
14:d9dfeeaff7e8 15:1fa5b5fa49e1
142 142
143 int init_tuntap() { 143 int init_tuntap() {
144 char* envval; 144 char* envval;
145 fprintf(stderr, "Initializing tun/tap device...\n"); 145 fprintf(stderr, "Initializing tun/tap device...\n");
146 int ttfd; //Tap device file descriptor 146 int ttfd; //Tap device file descriptor
147 #ifdef linux
148 struct ifreq ifr; //required for tun/tap setup
149 memset(&ifr, 0, sizeof(ifr));
150 if ((ttfd = open("/dev/net/tun", O_RDWR)) < 0) return errorexitp("Could not open tun/tap device file");
151 if (envval = getconf("INTERFACE")) strcpy(ifr.ifr_name, envval);
152 ifr.ifr_flags = getconf("TUN_MODE") ? IFF_TUN : IFF_TAP;
153 ifr.ifr_flags |= getconf("USE_PI") ? 0 : IFF_NO_PI;
154 if (ioctl(ttfd, TUNSETIFF, (void *)&ifr) < 0) return errorexitp("TUNSETIFF ioctl failed");
155 #else
147 #ifdef SOLARIS 156 #ifdef SOLARIS
148 int ip_fd = -1, if_fd = -1, ppa = 0; 157 int ip_fd = -1, if_fd = -1, ppa = 0;
149 #endif 158 if ((ttfd = open("/dev/tun", O_RDWR)) < 0) return errorexitp("Could not open tun device file");
150 #ifdef linux 159 if ((ip_fd = open("/dev/ip", O_RDWR, 0)) < 0) return errorexitp("Could not open /dev/ip");
151 struct ifreq ifr; //required for tun/tap setup 160 if ((envval = getconf("INTERFACE"))) {
152 memset(&ifr, 0, sizeof(ifr)); 161 while (*envval && !isdigit((int)*envval)) envval++;
153 if ((ttfd = open("/dev/net/tun", O_RDWR)) < 0) return errorexitp("Could not open tun/tap device file"); 162 ppa = atoi(envval);
154 if (envval = getconf("INTERFACE")) strcpy(ifr.ifr_name, envval); 163 }
155 ifr.ifr_flags = getconf("TUN_MODE") ? IFF_TUN : IFF_TAP; 164 if ((ppa = ioctl(ttfd, TUNNEWPPA, ppa)) < 0) return errorexitp("Could not assign new PPA");
156 ifr.ifr_flags |= getconf("USE_PI") ? 0 : IFF_NO_PI; 165 if ((if_fd = open("/dev/tun", O_RDWR, 0)) < 0) return errorexitp("Could not open tun device file again");
157 if (ioctl(ttfd, TUNSETIFF, (void *)&ifr) < 0) return errorexitp("TUNSETIFF ioctl failed"); 166 if (ioctl(if_fd, I_PUSH, "ip") < 0) return errorexitp("Could not push IP module");
158 #else 167 if (ioctl(if_fd, IF_UNITSEL, (char *)&ppa) < 0) return errorexitp("Could not set PPA");
159 #ifdef SOLARIS 168 if (ioctl(ip_fd, I_LINK, if_fd) < 0) return errorexitp("Could not link TUN device to IP");
160 if ((ttfd = open("/dev/tun", O_RDWR)) < 0) 169 #else
161 return errorexitp("Could not open tun device file"); 170 if (!(envval = getconf("INTERFACE"))) envval = "/dev/tun0";
162 171 if ((ttfd = open(envval, O_RDWR)) < 0) return errorexitp("Could not open tun device file");
163 if ((ip_fd = open("/dev/ip", O_RDWR, 0)) < 0) 172 #endif
164 return errorexitp("Could not open /dev/ip");
165
166 if ((envval = getconf("INTERFACE"))) {
167 while (*envval && !isdigit((int)*envval))
168 envval++;
169 ppa = atoi(envval);
170 }
171
172 if ((ppa = ioctl(ttfd, TUNNEWPPA, ppa)) < 0)
173 return errorexitp("Could not assign new PPA");
174
175 if ((if_fd = open("/dev/tun", O_RDWR, 0)) < 0)
176 return errorexitp("Could not open tun device file again");
177
178 if (ioctl(if_fd, I_PUSH, "ip") < 0)
179 return errorexitp("Could not push IP module");
180
181 if (ioctl(if_fd, IF_UNITSEL, (char *)&ppa) < 0)
182 return errorexitp("Could not set PPA");
183
184 if (ioctl(ip_fd, I_LINK, if_fd) < 0)
185 return errorexitp("Could not link TUN device to IP");
186 #else
187 if (!(envval = getconf("INTERFACE"))) envval = "/dev/tun0";
188 if ((ttfd = open(envval, O_RDWR)) < 0) return errorexitp("Could not open tun device file");
189 #endif
190 #endif 173 #endif
191 return ttfd; 174 return ttfd;
192 } 175 }
193 176
194 void hex2bin(unsigned char* dest, unsigned char* src, int count) { 177 void hex2bin(unsigned char* dest, unsigned char* src, int count) {
246 len = read(ttfd, buffer_raw + p->offset_raw, p->buffersize_raw); 229 len = read(ttfd, buffer_raw + p->offset_raw, p->buffersize_raw);
247 if (session.remote_float == 0 || session.remote_float == 2) { 230 if (session.remote_float == 0 || session.remote_float == 2) {
248 len = p->encode(&session, buffer_raw, buffer_enc, len); 231 len = p->encode(&session, buffer_raw, buffer_enc, len);
249 if (len < 0) return len; 232 if (len < 0) return len;
250 if (session.remote_float == 0) { 233 if (session.remote_float == 0) {
251 write(sfd, buffer_enc + p->offset_enc, len); 234 len = write(sfd, buffer_enc + p->offset_enc, len);
252 } else { 235 } else {
253 sendto(sfd, buffer_enc + p->offset_enc, len, 0, (struct sockaddr*)&session.remote_addr, sizeof(session.remote_addr)); 236 len = sendto(sfd, buffer_enc + p->offset_enc, len, 0, (struct sockaddr*)&session.remote_addr, sizeof(session.remote_addr));
254 } 237 }
255 } 238 }
239 }
240 if (fds[1].revents & POLLERR) {
241 int out;
242 len = sizeof(out);
243 getsockopt(sfd, SOL_SOCKET, SO_ERROR, &out, &len);
244 fprintf(stderr, "Received error %d on udp socket\n", out);
256 } 245 }
257 if (fds[1].revents & POLLIN) { 246 if (fds[1].revents & POLLIN) {
258 socklen_t recvaddr_len = sizeof(recvaddr); 247 socklen_t recvaddr_len = sizeof(recvaddr);
259 if (session.remote_float == 0) { 248 if (session.remote_float == 0) {
260 len = read(sfd, buffer_enc + p->offset_enc, p->buffersize_enc); 249 len = read(sfd, buffer_enc + p->offset_enc, p->buffersize_enc);
261 } else { 250 } else {
262 len = recvfrom(sfd, buffer_enc + p->offset_enc, p->buffersize_enc, 0, (struct sockaddr*)&recvaddr, &recvaddr_len); 251 len = recvfrom(sfd, buffer_enc + p->offset_enc, p->buffersize_enc, 0, (struct sockaddr*)&recvaddr, &recvaddr_len);
263 } 252 }
264 if (len < 0) { 253 if (len < 0) {
265 int out; 254 long long out;
266 len = 4; 255 len = sizeof(out);
267 getsockopt(sfd, SOL_SOCKET, SO_ERROR, &out, &len); 256 getsockopt(sfd, SOL_SOCKET, SO_ERROR, &out, &len);
268 fprintf(stderr, "End of file on udp socket"); 257 fprintf(stderr, "Received end of file on udp socket (error %d)\n", out);
269 } else { 258 } else {
270 len = p->decode(&session, buffer_enc, buffer_raw, len); 259 len = p->decode(&session, buffer_enc, buffer_raw, len);
271 if (len != 0 && session.remote_float != 0 && (session.remote_addr.sin_addr.s_addr != recvaddr.sin_addr.s_addr || session.remote_addr.sin_port != recvaddr.sin_port)) { 260 if (len != 0 && session.remote_float != 0 && (session.remote_addr.sin_addr.s_addr != recvaddr.sin_addr.s_addr || session.remote_addr.sin_port != recvaddr.sin_port)) {
272 fprintf(stderr, "Remote endpoint has changed to %08X:%d\n", recvaddr.sin_addr, ntohs(recvaddr.sin_port)); 261 fprintf(stderr, "Remote endpoint has changed to %08X:%d\n", recvaddr.sin_addr.s_addr, ntohs(recvaddr.sin_port));
273 session.remote_addr = recvaddr; 262 session.remote_addr = recvaddr;
274 session.remote_float = 2; 263 session.remote_float = 2;
275 } 264 }
276 if (len < 0) return len; 265 if (len < 0) return len;
277 write(ttfd, buffer_raw + p->offset_raw, len); 266 write(ttfd, buffer_raw + p->offset_raw, len);