Beispiel #1
0
void set_adrs(SymTbl *tp) /* 変数・引数の番地割当 */
{
  int i, size = INTSIZE;

  switch (tp->nmKind) {
  case varId:                                                        /*  変数 */
    if (tp->aryLen > 0) size *= tp->aryLen;             /* 配列ならサイズ計算 */
    if (is_global()) tp->adrs = mallocG(size);                    /* 大域変数 */
    else             tp->adrs = mallocL(size);                    /* 局所変数 */
    break;
  case fncId:                                                        /*  関数 */
    tp->adrs = nextCodeCt();                          /* 関数入口アドレス設定 */
    for (i=1; i<=tp->args; i++) {
      (tp+i)->adrs = mallocL(size);                     /* 引数のアドレス割当 */
    }
  }
}
// returns -1 for failures including the other end closing the socket
// returns 0 if successful in reading data, but still not read the data fully
// returns 1 if successful in reading all the data
mDNSlocal int ProxyTCPRead(ProxyTCPInfo_t *tcpInfo)
{
    long n;
    mDNSBool closed; 

    if (tcpInfo->nread < 2)         // First read the two-byte length preceeding the DNS message
    {
        mDNSu8 *lenptr = (mDNSu8 *)&tcpInfo->replyLen;
        n = mDNSPlatformReadTCP(&tcpInfo->sock, lenptr + tcpInfo->nread, 2 - tcpInfo->nread, &closed);
        if (n < 0 || closed)
        {
            LogMsg("ProxyTCPRead: attempt to read message length failed");
            return -1;
        }

        tcpInfo->nread += n;
        if (tcpInfo->nread < 2)
        {
            LogMsg("ProxyTCPRead: nread %d, n %d", tcpInfo->nread, n);
            return 0;
        }

        tcpInfo->replyLen = (mDNSu16)((mDNSu16)lenptr[0] << 8 | lenptr[1]);
        if (tcpInfo->replyLen < sizeof(DNSMessageHeader))
        {
            LogMsg("ProxyTCPRead: Message length too short (%d bytes)", tcpInfo->replyLen);
            return -1;
        }

        tcpInfo->reply = mallocL("ProxyTCPInfo", tcpInfo->replyLen);
        if (!tcpInfo->reply)
        {
            LogMsg("ProxyTCPRead: Memory failure");
            return -1;
        }
    }

    n = mDNSPlatformReadTCP(&tcpInfo->sock, ((char *)tcpInfo->reply) + (tcpInfo->nread - 2), tcpInfo->replyLen - (tcpInfo->nread - 2), &closed);

    if (n < 0 || closed)
    {
        LogMsg("ProxyTCPRead: read failure n %d, closed %d", n, closed);
        return -1;
    }
    tcpInfo->nread += n;
    if ((tcpInfo->nread - 2) != tcpInfo->replyLen)
        return 0;
    else 
        return 1;
}
mDNSlocal void ProxyTCPAccept(int s1, short filter, void *context)
{
    int newfd;
    struct sockaddr_storage ss;
    socklen_t sslen = sizeof(ss);
    const int on = 1;
    KQSocketSet *listenSet = (KQSocketSet *)context;

    (void) filter;

    while ((newfd = accept(s1, (struct sockaddr *)&ss, &sslen)) != -1)
    {
        int err;
        int *s;
        KQueueEntry *k;
        KQSocketSet *kq;

        // Even though we just need a single KQueueEntry, for simplicity we re-use
        // the KQSocketSet
        ProxyTCPInfo_t *ti = mallocL("ProxyTCPContext", sizeof(ProxyTCPInfo_t));
        if (!ti)
        {
            LogMsg("ProxyTCPAccept: cannot allocate TCPSocket");
            close(newfd);
            return;
        }
        mDNSPlatformMemZero(ti, sizeof(ProxyTCPInfo_t));
        TCPSocket *sock = &ti->sock;

        kq = &sock->ss;
        kq->sktv4 = -1;
        kq->sktv6 = -1;
        kq->m = listenSet->m;

        fcntl(newfd, F_SETFL, fcntl(newfd, F_GETFL, 0) | O_NONBLOCK); // set non-blocking
        if (ss.ss_family == AF_INET)
        {
            s =  &kq->sktv4;
            k =  &kq->kqsv4;
            // Receive interface identifiers
            err = setsockopt(newfd, IPPROTO_IP, IP_RECVIF, &on, sizeof(on));
            if (err)
            {
                LogMsg("ProxyTCPAccept: IP_RECVIF %d errno %d (%s)", newfd, errno, strerror(errno));
                mDNSPlatformDisposeProxyContext(ti);
                return;
            }
        }
        else
        {
            s =  &kq->sktv6;
            k =  &kq->kqsv6;
            // We want to receive destination addresses and receive interface identifiers
            err = setsockopt(newfd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, sizeof(on));
            if (err)
            {
                LogMsg("ProxyTCPAccept: IP_RECVPKTINFO %d errno %d (%s)", newfd, errno, strerror(errno));
                mDNSPlatformDisposeProxyContext(ti);
                return;
            }
        }
        *s = newfd;
        // mDNSPlatformReadTCP/WriteTCP (unlike the UDP counterpart) does not provide the destination address
        // from which we can infer the destination address family. Hence we need to remember that here.
        // Instead of remembering the address family, we remember the right fd.
        sock->fd = newfd;
        sock->kqEntry = k;

        k->KQcallback = ProxyTCPSocketCallBack;
        k->KQcontext  = ti;
        k->KQtask     = "TCP Proxy packet reception";
#ifdef MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM
        k->readSource = mDNSNULL;
        k->writeSource = mDNSNULL;
        k->fdClosed = mDNSfalse;
#endif
        KQueueSet(*s, EV_ADD, EVFILT_READ, k);
    }
}