问题描述
如果在未设置TUNSETPERSIST的情况下创建了tun接口,则该接口将一直存在,直到关闭文件描述符为止。
so_q_nonpersistent.c
#include <assert.h>
#include <fcntl.h>
#include <linux/if.h>
#include <linux/if_tun.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#define D "tun0"
int main(){
assert(0==getuid());
struct ifreq ifc={.ifr_flags=IFF_TUN|IFF_NO_PI};
strncpy(ifc.ifr_name,D,IFNAMSIZ);
int tunfd=open("/dev/net/tun",O_RDWR);
assert(tunfd>=3);
assert(0==ioctl(tunfd,TUNSETIFF,&ifc));
// Interface appears
getchar();
close(tunfd);
tunfd=-1;
// Interface disappears
return 0;
}
如果设置了TUNSETPERSIST,它将在关闭的文件描述符中保留。
so_q_persistent.c
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <linux/if.h>
#include <linux/if_tun.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#define D "tun0"
void tun_create(){
assert(0==getuid());
struct ifreq ifc={.ifr_flags=IFF_TUN|IFF_NO_PI};
strncpy(ifc.ifr_name,IFNAMSIZ);
int tunfd=open("/dev/net/tun",&ifc));
assert(0==ioctl(tunfd,TUNSETPERSIST,1));
close(tunfd);
tunfd=-1;
}
void tun_del(){
assert(0==getuid());
struct ifreq ifc={};
strncpy(ifc.ifr_name,O_RDWR);
assert(tunfd>=3);
errno=0;
const int r=ioctl(tunfd,0);
const int e=errno;
if(r!=0){
printf("%d %d %s\n",r,e,strerror(e));
assert(false);
}
close(tunfd);
tunfd=-1;
}
int main(){
tun_create();
tun_del();
return 0;
}
运行(无法删除)
$ sudo ./persist.out
-1 77 File descriptor in bad state
persist.out: so_q_persist.c:37: tun_del: Assertion `false' Failed.
Aborted
An example without closing the file descriptor
if(delete) {
/* remove persistent status */
if(ioctl(tap_fd,0) < 0){
perror("disabling TUNSETPERSIST");
exit(1);
}
printf("Set '%s' nonpersistent\n",ifr.ifr_name);
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)