で BSD ソケットを作成しsocket
、それを試みてlisten
います。を呼び出すとlisten
、ファイアウォールがアクティブなときにアプリケーション ファイアウォール ダイアログが表示されますが、ユーザーが操作するにはあまりにも早く消えてしまいます。listen
デバッガーでのブレークポイントの追加や への呼び出しなど、への呼び出しにほとんど遅延があると、 へのsleep
呼び出し後にsocket
ダイアログが表示され、ユーザーが対話するのに十分な時間留まることがわかりました。ユーザーが何かを選択する前にダイアログが消えた場合、ファイアウォールはそのアプリへの後続の着信要求をすべて拒否します。
ダイアログが消える原因と、それを防ぐためのより適切な方法があるかどうかを知っている人はいますsleep
か?
誰かがこれを試して再現したい場合は、この動作を引き起こすコードを以下に添付します. true の場合waitForUserInput
、ダイアログが表示され、ソケットが閉じられるまで残ります。そうでない場合、ダイアログは一瞬で消えます。をテストする行にブレークポイントを追加するとwaitForUserInput
、その変数が であってもダイアログが 5 秒間表示されますNO
。これらすべての場合において、 への呼び出しlisten
はエラーを返しません。OS X 10.7.4 と Xcode 4.2 を使用しています。
#import <sys/socket.h>
#import <netdb.h>
static void firewallDialog(BOOL waitForUserInput){
struct addrinfo *res, *p, host;
memset(&host, 0, sizeof host);
host.ai_family = AF_UNSPEC; // no preference for IP4/6
host.ai_socktype = SOCK_STREAM; // TCP
host.ai_flags = AI_PASSIVE; // local IP address
if(-1 != (getaddrinfo(NULL,"1234",&host,&res))){
int sock = -1;
for(p = res; p != NULL; sock = -1, p = p->ai_next) {
// make a socket
if(-1 == (sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol))){
continue;
}
if(p->ai_family == PF_INET6){
((struct sockaddr_in6*)p->ai_addr)->sin6_addr = in6addr_any;
}
if(-1 == bind(sock, p->ai_family == PF_INET ? INADDR_ANY : p->ai_addr, p->ai_addrlen)){
close(sock);
continue;
}
break;
}
freeaddrinfo(res);
if(-1 != sock){
if(waitForUserInput){ sleep(1); }
if(-1 == listen(sock, 20)){
close(sock);
}else{
NSLog(@"Call to listen was successful");
sleep(5);
close(sock);
}
}
}
}