⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 macsockotpt.c

📁 Netscape NSPR库源码
💻 C
📖 第 1 页 / 共 5 页
字号:
            return;        case T_PASSCON:  // State is now T_DATAXFER            // OTAccept() complete, receiving endpoint in T_DATAXFER state            // cookie = OTAccept() resRef parameter            break;        case T_RESET:    // Protocol has been reset            PR_ASSERT(!"T_RESET Not implemented");            return;            // Async Completion Events        case T_BINDCOMPLETE:        case T_UNBINDCOMPLETE:        case T_ACCEPTCOMPLETE:        case T_OPTMGMTCOMPLETE:        case T_GETPROTADDRCOMPLETE:            readThread = secret->md.misc.thread;            secret->md.misc.thread    = NULL;            secret->md.misc.cookie    = cookie;            break;//      case T_OPENCOMPLETE:            // we open endpoints in synchronous mode//      case T_REPLYCOMPLETE://      case T_DISCONNECTCOMPLETE:      // we don't call OTSndDisconnect()//      case T_RESOLVEADDRCOMPLETE://      case T_GETINFOCOMPLETE://      case T_SYNCCOMPLETE://      case T_MEMORYRELEASED:          // only if OTAckSends() called on endpoint//      case T_REGNAMECOMPLETE://      case T_DELNAMECOMPLETE://      case T_LKUPNAMECOMPLETE://      case T_LKUPNAMERESULT:        // OpenTptInternet.h//      case T_DNRSTRINGTOADDRCOMPLETE: // DNS is handled by dnsContext in DNSNotifierRoutine()//      case T_DNRADDRTONAMECOMPLETE://      case T_DNRSYSINFOCOMPLETE://      case T_DNRMAILEXCHANGECOMPLETE://      case T_DNRQUERYCOMPLETE:        default:            // we should probably have a bit more sophisticated handling of kOTSystemSleep, etc.            // PR_ASSERT(code != 0);            return;    }    if (readThread)        WakeUpNotifiedThread(readThread, result);    if (writeThread && (writeThread != readThread))        WakeUpNotifiedThread(writeThread, result);}static OSErr CreateSocket(int type, EndpointRef *endpoint){    OSStatus err;    PRThread *me = _PR_MD_CURRENT_THREAD();    char *  configName;    OTConfiguration *config;    EndpointRef ep;    // for now we just create the endpoint    // we'll make it asynchronous and give it a notifier routine in _MD_makenonblock()    switch (type){        case SOCK_STREAM:   configName = kTCPName;  break;        case SOCK_DGRAM:    configName = kUDPName;  break;    }    config = OTCreateConfiguration(configName);    ep = OT_OPEN_ENDPOINT(config, 0, NULL, &err);    if (err != kOTNoError)        goto ErrorExit;    *endpoint = ep;    PR_ASSERT(*endpoint != NULL);    return kOTNoError;ErrorExit:    return err;}// Errors returned:// kOTXXXX - OT returned error// EPROTONOSUPPORT - bad socket type/protocol// ENOBUFS - not enough space for another socket, or failure in socket creation routinePRInt32 _MD_socket(int domain, int type, int protocol){    OSStatus    err;    EndpointRef endpoint;        _MD_FinishInitNetAccess();    // We only deal with internet domain    if (domain != AF_INET) {        err = kEPROTONOSUPPORTErr;        goto ErrorExit;    }        // We only know about tcp & udp    if ((type != SOCK_STREAM) && (type != SOCK_DGRAM)) {        err = kEPROTONOSUPPORTErr;        goto ErrorExit;    }        // Convert default types to specific types.    if (protocol == 0)  {        if (type == SOCK_DGRAM)            protocol = IPPROTO_UDP;        else if (type == SOCK_STREAM)            protocol = IPPROTO_TCP;    }        // Only support default protocol for tcp    if ((type == SOCK_STREAM)  && (protocol != IPPROTO_TCP)) {        err = kEPROTONOSUPPORTErr;        goto ErrorExit;    }                    // Only support default protocol for udp    if ((type == SOCK_DGRAM)  && (protocol != IPPROTO_UDP)) {        err = kEPROTONOSUPPORTErr;        goto ErrorExit;    }            // Create a socket, we might run out of memory    err = CreateSocket(type, &endpoint);    if (err != kOTNoError)        goto ErrorExit;    PR_ASSERT((PRInt32)endpoint != -1);    return ((PRInt32)endpoint);ErrorExit:    macsock_map_error(err);    return -1;}// Errors:// EBADF  -- bad socket id// EFAULT -- bad address formatPRInt32 _MD_bind(PRFileDesc *fd, PRNetAddr *addr, PRUint32 addrlen){    OSStatus err;    EndpointRef endpoint = (EndpointRef) fd->secret->md.osfd;    TBind bindReq;    PRThread *me = _PR_MD_CURRENT_THREAD();    PRUint32 retryCount = 0;    if (endpoint == NULL) {        err = kEBADFErr;        goto ErrorExit;    }            if (addr == NULL) {        err = kEFAULTErr;        goto ErrorExit;    }        /* * There seems to be a bug with OT related to OTBind failing with kOTNoAddressErr even though * a proper legal address was supplied.  This happens very rarely and just retrying the * operation after a certain time (less than 1 sec. does not work) seems to succeed. */TryAgain:    // setup our request    bindReq.addr.len = addrlen;            bindReq.addr.maxlen = addrlen;    bindReq.addr.buf = (UInt8*) addr;    bindReq.qlen = 1;	PR_Lock(fd->secret->md.miscLock);    PrepareForAsyncCompletion(me, fd->secret->md.osfd);	fd->secret->md.misc.thread = me;    err = OTBind(endpoint, &bindReq, NULL);    if (err != kOTNoError) {	    me->io_pending = PR_FALSE;	    PR_Unlock(fd->secret->md.miscLock);        goto ErrorExit;	}    WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT);	PR_Unlock(fd->secret->md.miscLock);    err = me->md.osErrCode;    if (err != kOTNoError)        goto ErrorExit;    return kOTNoError;ErrorExit:    if ((err == kOTNoAddressErr) && (++retryCount <= 4)) {        unsigned long finalTicks;            Delay(100,&finalTicks);        goto TryAgain;    }    macsock_map_error(err);    return -1;}// Errors:// EBADF -- bad socket idPRInt32 _MD_listen(PRFileDesc *fd, PRIntn backlog){    PRInt32 osfd = fd->secret->md.osfd;    OSStatus err = 0;    EndpointRef endpoint = (EndpointRef) osfd;    TBind bindReq;    PRNetAddr addr;    PRThread *me = _PR_MD_CURRENT_THREAD();	if ((fd == NULL) || (endpoint == NULL)) {		err = EBADF;		goto ErrorExit;	}    if (backlog == 0)        backlog = 1;    if (endpoint == NULL) {        err = EBADF;        goto ErrorExit;    }            addr.inet.family = AF_INET;    addr.inet.port = addr.inet.ip = 0;    bindReq.addr.maxlen = PR_NETADDR_SIZE (&addr);    bindReq.addr.len = 0;    bindReq.addr.buf = (UInt8*) &addr;    bindReq.qlen = 0;        PrepareForAsyncCompletion(me, fd->secret->md.osfd);    	fd->secret->md.misc.thread = me; // tell notifier routine what to wake up    err = OTGetProtAddress(endpoint, &bindReq, NULL);    if (err != kOTNoError)        goto ErrorExit;    WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT);    err = me->md.osErrCode;    if (err != kOTNoError)        goto ErrorExit;    PrepareForAsyncCompletion(me, fd->secret->md.osfd);    	fd->secret->md.misc.thread = me; // tell notifier routine what to wake up    err = OTUnbind(endpoint);    if (err != kOTNoError)        goto ErrorExit;    WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT);    err = me->md.osErrCode;    if (err != kOTNoError)        goto ErrorExit;	/* tell the notifier func that we are interested in pending connections */	fd->secret->md.doListen = PR_TRUE;	/* accept up to (backlog) pending connections at any one time */    bindReq.qlen = backlog;        PrepareForAsyncCompletion(me, fd->secret->md.osfd);    	fd->secret->md.misc.thread = me; // tell notifier routine what to wake up    err = OTBind(endpoint, &bindReq, NULL);    if (err != kOTNoError)        goto ErrorExit;    WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT);    err = me->md.osErrCode;    if (err != kOTNoError)    {    	// If OTBind failed, we're really not ready to listen after all.		fd->secret->md.doListen = PR_FALSE;        goto ErrorExit;    }    return kOTNoError;ErrorExit:	me->io_pending = PR_FALSE; // clear pending wait state if any    macsock_map_error(err);    return -1;}// Errors:// EBADF -- bad socket idPRInt32 _MD_getsockname(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen){    OSStatus err;    EndpointRef endpoint = (EndpointRef) fd->secret->md.osfd;    TBind bindReq;    PRThread *me = _PR_MD_CURRENT_THREAD();    if (endpoint == NULL) {        err = kEBADFErr;        goto ErrorExit;    }            if (addr == NULL) {        err = kEFAULTErr;        goto ErrorExit;    }    bindReq.addr.len = *addrlen;    bindReq.addr.maxlen = *addrlen;    bindReq.addr.buf = (UInt8*) addr;    bindReq.qlen = 0;    	PR_Lock(fd->secret->md.miscLock);    PrepareForAsyncCompletion(me, fd->secret->md.osfd);    	fd->secret->md.misc.thread = me;    err = OTGetProtAddress(endpoint, &bindReq, NULL);    if (err != kOTNoError) {	    me->io_pending = PR_FALSE;	    PR_Unlock(fd->secret->md.miscLock);        goto ErrorExit;	}    WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT);	PR_Unlock(fd->secret->md.miscLock);    err = me->md.osErrCode;    if (err != kOTNoError)        goto ErrorExit;    *addrlen = PR_NETADDR_SIZE(addr);    return kOTNoError;ErrorExit:    macsock_map_error(err);    return -1;}PRStatus _MD_getsockopt(PRFileDesc *fd, PRInt32 level, PRInt32 optname, char* optval, PRInt32* optlen){    OSStatus err;    EndpointRef endpoint = (EndpointRef) fd->secret->md.osfd;    TOptMgmt cmd;    TOption *opt;    PRThread *me = _PR_MD_CURRENT_THREAD();    unsigned char optionBuffer[kOTOptionHeaderSize + sizeof(PRSocketOptionData)];        if (endpoint == NULL) {        err = kEBADFErr;        goto ErrorExit;    }        /*     OT wants IPPROTO_IP for level and not XTI_GENERIC.  SO_REUSEADDR and SO_KEEPALIVE     are equated to IP level and TCP level options respectively and hence we need to set     the level correctly.    */    if (level == SOL_SOCKET) {        if (optname == SO_REUSEADDR)            level = IPPROTO_IP;        else if (optname == SO_KEEPALIVE)            level = INET_TCP;    }    opt = (TOption *)&optionBuffer[0];    opt->len = sizeof(TOption);    opt->level = level;    opt->name = optname;    opt->status = 0;        cmd.opt.len = sizeof(TOption);    cmd.opt.maxlen = sizeof(optionBuffer);    cmd.opt.buf = (UInt8*)optionBuffer;    cmd.flags = T_CURRENT;	PR_Lock(fd->secret->md.miscLock);    PrepareForAsyncCompletion(me, fd->secret->md.osfd);    	fd->secret->md.misc.thread = me;    err = OTOptionManagement(endpoint, &cmd, &cmd);    if (err != kOTNoError) {	    me->io_pending = PR_FALSE;	    PR_Unlock(fd->secret->md.miscLock);        goto ErrorExit;	}    WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT);	PR_Unlock(fd->secret->md.miscLock);    err = me->md.osErrCode;    if (err != kOTNoError)        goto ErrorExit;    if (opt->status == T_FAILURE || opt->status == T_NOTSUPPORT){        err = kEOPNOTSUPPErr;        goto ErrorExit;    }    PR_ASSERT(opt->status == T_SUCCESS);    switch (optname) {        case SO_LINGER:            *((t_linger*)optval) = *((t_linger*)&opt->value);            *optlen = sizeof(t_linger);            break;        case SO_REUSEADDR:        case TCP_NODELAY:        case SO_KEEPALIVE:        case SO_RCVBUF:        case SO_SNDBUF:            *((PRIntn*)optval) = *((PRIntn*)&opt->value);            *optlen = sizeof(PRIntn);            break;        case IP_MULTICAST_LOOP:            *((PRUint8*)optval) = *((PRIntn*)&opt->value);            *optlen = sizeof(PRUint8);            break;        case IP_TTL:            *((PRUintn*)optval) = *((PRUint8*)&opt->value);            *optlen = sizeof(PRUintn);            break;        case IP_MULTICAST_TTL:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -