2

で 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);
            }
        }
    }
}
4

0 に答える 0