Exemplo n.º 1
0
static AJ_Status AuthAdvance(AJ_SASL_Context* context, AJ_IOBuffer* rxBuf, AJ_IOBuffer* txBuf)
{
    AJ_Status status = AJ_OK;

    AJ_InfoPrintf(("AuthAdvance(context=0x%p, rxBuf=0x%p, txBuf=0x%p)\n", context, rxBuf, txBuf));

    if (context->state != AJ_SASL_SEND_AUTH_REQ) {
        /*
         * All the authentication messages end in a CR/LF so read until we get a newline
         */
        while ((AJ_IO_BUF_AVAIL(rxBuf) == 0) || (*(rxBuf->writePtr - 1) != '\n')) {
            status = rxBuf->recv(rxBuf, AJ_IO_BUF_SPACE(rxBuf), 3500);
            if (status != AJ_OK) {
                break;
            }
        }
    }
    if (status == AJ_OK) {
        uint32_t inLen = AJ_IO_BUF_AVAIL(rxBuf);
        *rxBuf->writePtr = '\0';
        status = AJ_SASL_Advance(context, (char*)rxBuf->readPtr, (char*)txBuf->writePtr, AJ_IO_BUF_SPACE(txBuf));
        if (status == AJ_OK) {
            rxBuf->readPtr += inLen;
            txBuf->writePtr += strlen((char*)txBuf->writePtr);
            status = txBuf->send(txBuf);
        }
    }
    return status;
}
Exemplo n.º 2
0
/*
 * Make sure we have the required number of bytes in the I/O buffer
 */
static AJ_Status LoadBytes(AJ_IOBuffer* ioBuf, uint16_t numBytes, uint8_t pad)
{
    AJ_Status status = AJ_OK;

    numBytes += pad;
    /*
     * Needs to be enough headroom in the buffer to satisfy the read
     */
    if (numBytes > (ioBuf->bufSize - AJ_IO_BUF_CONSUMED(ioBuf))) {
        return AJ_ERR_RESOURCES;
    }
    while (AJ_IO_BUF_AVAIL(ioBuf) < numBytes) {
        //#pragma calls = AJ_Net_Recv
        status = ioBuf->recv(ioBuf, numBytes - AJ_IO_BUF_AVAIL(ioBuf), UNMARSHAL_TIMEOUT);
        if (status != AJ_OK) {
            /*
             * Timeouts after we have started to unmarshal a message are a bad sign.
             */
            if (status == AJ_ERR_TIMEOUT) {
                status = AJ_ERR_READ;
            }
            break;
        }
    }
    /*
     * Skip over pad bytes (The wire protocol says these should be zeroes)
     */
    ioBuf->readPtr += pad;
    return status;
}
Exemplo n.º 3
0
static AJ_Status AJ_Net_Send(AJ_IOBuffer* buf)
{
    DWORD ret;
    DWORD tx = AJ_IO_BUF_AVAIL(buf);

    AJ_InfoPrintf(("AJ_Net_Send(buf=0x%p)\n", buf));

    assert(buf->direction == AJ_IO_BUF_TX);

    if (tx > 0) {
        NetContext* ctx = (NetContext*) buf->context;
        WSAOVERLAPPED ov;
        DWORD flags = 0;
        WSABUF wsbuf;

        memset(&ov, 0, sizeof(ov));
        ov.hEvent = sendEvent;
        wsbuf.len = tx;
        wsbuf.buf = buf->readPtr;

        ret = WSASend(ctx->tcpSock, &wsbuf, 1, NULL, flags, &ov, NULL);
        if (!WSAGetOverlappedResult(ctx->tcpSock, &ov, &tx, TRUE, &flags)) {
            AJ_ErrPrintf(("AJ_Net_Send(): send() failed. WSAGetLastError()=0x%x, status=AJ_ERR_WRITE\n", WSAGetLastError()));
            return AJ_ERR_WRITE;
        }
        buf->readPtr += tx;
    }
    if (AJ_IO_BUF_AVAIL(buf) == 0) {
        AJ_IO_BUF_RESET(buf);
    }
    AJ_InfoPrintf(("AJ_Net_Send(): status=AJ_OK\n"));
    return AJ_OK;
}
Exemplo n.º 4
0
//-----------------------------------------------------------------------------
AJ_Status AJ_Net_Send(AJ_IOBuffer* buf)
{
    uint32_t ret;
    uint32_t tx = AJ_IO_BUF_AVAIL(buf);

    printf("AJ_Net_Send(buf=0x%p)\n", buf);
 //   printf("tcp_client_socket=%d", tcp_client_socket);
    if (tx > 0) 
	{
      //  ret = g_client.write(buf->readPtr, tx);
		send(tcp_client_socket, buf->readPtr, tx, 0);
	//	while(tcp_tx_ready==0) m2m_wifi_handle_events(NULL);
     /*   if (ret != 0) 
		{
            //AJ_ErrPrintf(("AJ_Net_Send(): send() failed. error=%d, status=AJ_ERR_WRITE\n", g_client.getWriteError()));
            return AJ_ERR_WRITE;
        }*/
		
        buf->readPtr += tcp_tx_ready;
		tcp_tx_ready=0;
    }
 //   if (AJ_IO_BUF_AVAIL(buf) == 0)
//	{
	       AJ_IO_BUF_RESET(buf);
//	}
    //printf("AJ_Net_Send end\n");
    return AJ_OK;
}
Exemplo n.º 5
0
AJ_Status AJ_Net_SendTo(AJ_IOBuffer* buf)
{
    int ret;
    uint32_t tx = AJ_IO_BUF_AVAIL(buf);

    //AJ_InfoPrintf(("AJ_Net_SendTo(buf=0x%p)\n", buf));

    if (tx > 0)
	{
  	    ret = sendto(rx_socket, buf->readPtr, tx, 0, (struct sockaddr *)&addr, sizeof(addr));
		m2m_wifi_handle_events(NULL);
        //AJ_InfoPrintf(("AJ_Net_SendTo(): SendTo write %d\n", ret));
        if (sock_tx_state != 1) 
		{
            //AJ_ErrPrintf(("AJ_Net_Sendto(): no bytes. status=AJ_ERR_WRITE\n"));
            return AJ_ERR_WRITE;
        }

        buf->readPtr += ret;

    }
    AJ_IO_BUF_RESET(buf);
    //AJ_InfoPrintf(("AJ_Net_SendTo(): status=AJ_OK\n"));
    return AJ_OK;
}
Exemplo n.º 6
0
AJ_Status AJ_CloseMsg(AJ_Message* msg)
{
    AJ_Status status = AJ_OK;
    /*
     * This function is idempotent
     */
    if (msg->bus) {
        AJ_IOBuffer* ioBuf = &msg->bus->sock.rx;
        /*
         * Skip any unconsumed bytes
         */
        while (msg->bodyBytes) {
            uint16_t sz = AJ_IO_BUF_AVAIL(ioBuf);
            sz = min(sz, msg->bodyBytes);
            if (!sz) {
                AJ_IO_BUF_RESET(ioBuf);
                sz = min(msg->bodyBytes, ioBuf->bufSize);
            }
            status = LoadBytes(ioBuf, sz, 0);
            if (status != AJ_OK) {
                break;
            }
            msg->bodyBytes -= sz;
            ioBuf->readPtr += sz;
        }
        memset(msg, 0, sizeof(AJ_Message));
#ifndef NDEBUG
        currentMsg = NULL;
#endif
    }
    return status;
}
Exemplo n.º 7
0
AJ_Status AJ_Net_Send(AJ_IOBuffer* buf)
{
    uint32_t ret;
    uint32_t tx = AJ_IO_BUF_AVAIL(buf);

    AJ_InfoPrintf(("AJ_Net_Send(buf=0x%p)\n", buf));

    if (tx > 0) {
        ret = g_client.write(buf->readPtr, tx);
        if (ret == 0) {
            AJ_ErrPrintf(("AJ_Net_Send(): send() failed. error=%d, status=AJ_ERR_WRITE\n", g_client.getWriteError()));
            return AJ_ERR_WRITE;
        }
        buf->readPtr += ret;
    }
    if (AJ_IO_BUF_AVAIL(buf) == 0) {
        AJ_IO_BUF_RESET(buf);
    }

    AJ_InfoPrintf(("AJ_Net_Send(): status=AJ_OK\n"));
    return AJ_OK;
}
Exemplo n.º 8
0
static AJ_Status ReadLine(AJ_IOBuffer* rxBuf) {
    /*
     * All the authentication messages end in a CR/LF so read until we get a newline
     */
    AJ_Status status = AJ_OK;
    while ((AJ_IO_BUF_AVAIL(rxBuf) == 0) || (*(rxBuf->writePtr - 1) != '\n')) {
        status = rxBuf->recv(rxBuf, AJ_IO_BUF_SPACE(rxBuf), 3500);
        if (status != AJ_OK) {
            break;
        }
    }
    return status;
}
Exemplo n.º 9
0
void AJ_IOBufRebase(AJ_IOBuffer* ioBuf, size_t preserve)
{
    int32_t unconsumed = AJ_IO_BUF_AVAIL(ioBuf);
    /*
     * Move any unconsumed data to the start of the I/O buffer
     */
    if (unconsumed) {
        memmove(ioBuf->bufStart + preserve, ioBuf->readPtr, unconsumed);
    }

    ioBuf->readPtr = ioBuf->bufStart + preserve;
    ioBuf->writePtr = ioBuf->bufStart + preserve + unconsumed;
}
Exemplo n.º 10
0
static AJ_Status TxFunc(AJ_IOBuffer* buf)
{
    size_t tx = AJ_IO_BUF_AVAIL(buf);;


    if ((wireBytes + tx) > sizeof(wireBuffer)) {
        return AJ_ERR_WRITE;
    } else {
        memcpy(wireBuffer + wireBytes, buf->bufStart, tx);
        AJ_IO_BUF_RESET(buf);
        wireBytes += tx;
        return AJ_OK;
    }
}
Exemplo n.º 11
0
AJ_Status AJ_Net_SendTo(AJ_IOBuffer* buf)
{
    int ret;
    uint32_t tx = AJ_IO_BUF_AVAIL(buf);

    AJ_InfoPrintf(("AJ_Net_SendTo(buf=0x%p)\n", buf));

    if (tx > 0) {
        // send to subnet-directed broadcast address
#ifdef WIFI_UDP_WORKING
        IPAddress subnet = WiFi.subnetMask();
        IPAddress localIp = WiFi.localIP();
#else
        IPAddress subnet = Ethernet.subnetMask();
        IPAddress localIp = Ethernet.localIP();
#endif
        uint32_t directedBcastAddr = (uint32_t(subnet) & uint32_t(localIp)) | (~uint32_t(subnet));
        IPAddress a(directedBcastAddr);
        ret = g_clientUDP.beginPacket(IPAddress(directedBcastAddr), AJ_UDP_PORT);
        AJ_InfoPrintf(("AJ_Net_SendTo(): beginPacket to %d.%d.%d.%d, result = %d\n", a[0], a[1], a[2], a[3], ret));
        if (ret == 0) {
            AJ_InfoPrintf(("AJ_Net_SendTo(): no sender\n"));
        }

        ret = g_clientUDP.write(buf->readPtr, tx);
        AJ_InfoPrintf(("AJ_Net_SendTo(): SendTo write %d\n", ret));
        if (ret == 0) {
            AJ_ErrPrintf(("AJ_Net_Sendto(): no bytes. status=AJ_ERR_WRITE\n"));
            return AJ_ERR_WRITE;
        }

        buf->readPtr += ret;

        ret = g_clientUDP.endPacket();
        if (ret == 0) {
            AJ_ErrPrintf(("AJ_Net_Sendto(): endPacket() error. status=AJ_ERR_WRITE\n"));
            return AJ_ERR_WRITE;
        }

    }
    AJ_IO_BUF_RESET(buf);
    AJ_InfoPrintf(("AJ_Net_SendTo(): status=AJ_OK\n"));
    return AJ_OK;
}
Exemplo n.º 12
0
AJ_Status AJ_ARDP_UDP_Connect(AJ_BusAttachment* bus, void* context, const AJ_Service* service, AJ_NetSocket* netSock)
{
    AJ_Message hello;
    AJ_GUID localGuid;
    char guid_buf[33];
    AJ_Status status;
    AJ_Message helloResponse;

    AJ_GetLocalGUID(&localGuid);
    AJ_GUID_ToString(&localGuid, guid_buf, sizeof(guid_buf));

    AJ_MarshalMethodCall(bus, &hello, AJ_METHOD_BUS_SIMPLE_HELLO, AJ_BusDestination, 0, AJ_FLAG_ALLOW_REMOTE_MSG, AJ_UDP_CONNECT_TIMEOUT);
    AJ_MarshalArgs(&hello, "su", guid_buf, 10);
    hello.hdr->bodyLen = hello.bodyBytes;

    status = AJ_ARDP_Connect(bus->sock.tx.readPtr, AJ_IO_BUF_AVAIL(&bus->sock.tx), context, netSock);
    if (status != AJ_OK) 
	{
        return status;
    }

    status = AJ_UnmarshalMsg(bus, &helloResponse, AJ_UDP_CONNECT_TIMEOUT);
    if (status == AJ_OK && helloResponse.msgId == AJ_REPLY_ID(AJ_METHOD_BUS_SIMPLE_HELLO)) 
	{
        if (helloResponse.hdr->msgType == AJ_MSG_ERROR) 
		{
            status = AJ_ERR_CONNECT;
        } 
		else 
		{
            AJ_Arg uniqueName, protoVersion;
            AJ_UnmarshalArg(&helloResponse, &uniqueName);
            AJ_SkipArg(&helloResponse);
            AJ_UnmarshalArg(&helloResponse, &protoVersion);

            /**
			* The two most-significant bits are reserved for the nameType,
			* which we don't currently care about in the thin client
			*/
            routingProtoVersion = (uint8_t) ((*protoVersion.val.v_uint32) & 0x3FFFFFFF);

            if (uniqueName.len >= (sizeof(bus->uniqueName) - 1))
			{
                AJ_ErrPrintf(("AJ_ARDP_Connect(): AJ_ERR_RESOURCES\n"));
                status = AJ_ERR_RESOURCES;
            } 
			else 
			{
                memcpy(bus->uniqueName, uniqueName.val.v_string, uniqueName.len);
                bus->uniqueName[uniqueName.len] = '\0';
            }

           /AJ_InfoPrintf(("Received name: %s and version %u\n", bus->uniqueName, routingProtoVersion));
            if (routingProtoVersion < AJ_GetMinProtoVersion()) 
			{
                AJ_InfoPrintf(("AJ_ARDP_Connect(): Blacklisting routing node, found %u but require >= %u\n",
                               routingProtoVersion, AJ_GetMinProtoVersion()));
                AddRoutingNodeToBlacklist(service);
                status = AJ_ERR_CONNECT;
            }
        }
    } 
Exemplo n.º 13
0
static void ResetRead(AJ_IOBuffer* rxBuf) 
{
    rxBuf->readPtr += AJ_IO_BUF_AVAIL(rxBuf);
    *rxBuf->writePtr = '\0';
}
Exemplo n.º 14
0
static AJ_Status ParseIsAt(AJ_IOBuffer* rxBuf, const char* prefix, AJ_Service* service)
{
    AJ_Status status = AJ_ERR_NO_MATCH;
    size_t preLen = strlen(prefix);
    NSHeader* hdr = (NSHeader*)rxBuf->readPtr;
    uint32_t len = AJ_IO_BUF_AVAIL(rxBuf);
    uint8_t* p = rxBuf->readPtr + 4;
    uint8_t* eod = (uint8_t*)hdr + len;

    AJ_InfoPrintf(("ParseIsAt(rxbuf=0x%p, prefix=\"%s\", service=0x%p)\n", rxBuf, prefix, service));

    service->addrTypes = 0;

    /*
     * Silently ignore versions we don't know how to parse
     */
    if (MSG_VERSION(hdr->version) != MSG_V1) {
        return status;
    }
    /*
     * Questions come in first - we currently ignore them
     */
    while (hdr->qCount--) {
        uint8_t flags = *p++;
        uint8_t nameCount = *p++;
        /*
         * Questions must be WHO_HAS messages
         */
        if (MSG_TYPE(flags) != WHO_HAS_MSG) {
            AJ_InfoPrintf(("ParseIsAt(): AJ_ERR_INVALID\n"));
            return AJ_ERR_INVALID;
        }
        while (nameCount--) {
            uint8_t sz = *p++;
            p += sz;
            if (p > eod) {
                AJ_InfoPrintf(("ParseIsAt(): AJ_ERR_END_OF_DATA\n"));
                status = AJ_ERR_END_OF_DATA;
                goto Exit;
            }
        }
    }
    /*
     * Now the answers - this is what we are looking for
     */
    while (hdr->aCount--) {
        uint8_t flags = *p++;
        uint8_t nameCount = *p++;
        /*
         * Answers must be IS_AT messages
         */
        if (MSG_TYPE(flags) != IS_AT_MSG) {
            AJ_InfoPrintf(("ParseIsAt(): AJ_ERR_INVALID\n"));
            return AJ_ERR_INVALID;
        }
        /*
         * Must be reliable IPV4 or IPV6
         */
        if (!(flags & (R4_FLAG | R6_FLAG))) {
            return status;
        }
        /*
         * Get transport mask
         */
        service->transportMask = (p[0] << 8) | p[1];
        p += 2;
        /*
         * Decode addresses
         */
        if (flags & R4_FLAG) {
            memcpy(&service->ipv4, p, sizeof(service->ipv4));
            p += sizeof(service->ipv4);
            service->ipv4port = (p[0] << 8) | p[1];
            p += 2;
            service->addrTypes |= AJ_ADDR_IPV4;
        }
        if (flags & U4_FLAG) {
            p += sizeof(service->ipv4) + 2;
        }
        if (flags & R6_FLAG) {
            memcpy(&service->ipv6, p, sizeof(service->ipv6));
            p += sizeof(service->ipv6);
            service->ipv6port = (p[0] << 8) | p[1];
            p += 2;
            service->addrTypes |= AJ_ADDR_IPV6;
        }
        if (flags & U6_FLAG) {
            p += sizeof(service->ipv6) + 2;
        }
        /*
         * Skip guid if it's present
         */
        if (flags & G_FLAG) {
            uint8_t sz = *p++;
            len -= 1 + sz;
            p += sz;
        }
        if (p >= eod) {
            AJ_InfoPrintf(("ParseIsAt(): AJ_ERR_END_OF_DATA\n"));
            return AJ_ERR_END_OF_DATA;
        }
        /*
         * Iterate over the names
         */
        while (nameCount--) {
            uint8_t sz = *p++;
            {
                char sav = p[sz];
                p[sz] = 0;
                AJ_InfoPrintf(("ParseIsAt(): Found \"%s\" IP 0x%x\n", p, service->addrTypes));
                p[sz] = sav;
            }
            if ((preLen <= sz) && (memcmp(p, prefix, preLen) == 0)) {
                status = AJ_OK;
                goto Exit;
            }
            p += sz;
            if (p > eod) {
                status = AJ_ERR_END_OF_DATA;
                AJ_InfoPrintf(("ParseIsAt(): AJ_ERR_END_OF_DATA\n"));
                goto Exit;
            }
        }
    }

Exit:
    return status;
}
Exemplo n.º 15
0
static AJ_Status AJ_Net_SendTo(AJ_IOBuffer* buf)
{
    DWORD ret;
    DWORD tx = AJ_IO_BUF_AVAIL(buf);
    int numWrites = 0;

    AJ_InfoPrintf(("AJ_Net_SendTo(buf=0x%p)\n", buf));

    assert(buf->direction == AJ_IO_BUF_TX);
    assert(NumMcastSocks > 0);

    if (tx > 0) {
        size_t i;

        // our router (hopefully) lives on one of the networks but we don't know which one.
        // send discovery requests to all of them.
        for (i = 0; i < NumMcastSocks; ++i) {
            SOCKET sock = McastSocks[i].sock;
            int family = McastSocks[i].family;

            if ((buf->flags & AJ_IO_BUF_AJ) && !McastSocks[i].is_mdns) {
                // try sending IPv6 multicast
                if (family == AF_INET6) {
                    struct sockaddr_in6 sin6;
                    memset(&sin6, 0, sizeof(struct sockaddr_in6));
                    sin6.sin6_family = AF_INET6;
                    sin6.sin6_port = htons(AJ_UDP_PORT);
                    inet_pton(AF_INET6, AJ_IPV6_MULTICAST_GROUP, &sin6.sin6_addr);
                    ret = sendto(sock, buf->readPtr, tx, 0, (struct sockaddr*) &sin6, sizeof(struct sockaddr_in6));
                    if (ret == SOCKET_ERROR) {
                        AJ_ErrPrintf(("AJ_Net_SendTo(): sendto() failed (IPV6). WSAGetLastError()=0x%x\n", WSAGetLastError()));
                    } else {
                        ++numWrites;
                    }
                }
                // try sending IPv4 multicast
                if (family == AF_INET && McastSocks[i].has_mcast4) {
                    struct sockaddr_in sin;
                    memset(&sin, 0, sizeof(sin));
                    sin.sin_family = AF_INET;
                    sin.sin_port = htons(AJ_UDP_PORT);
                    inet_pton(AF_INET, AJ_IPV4_MULTICAST_GROUP, &sin.sin_addr);

                    ret = sendto(sock, buf->readPtr, tx, 0, (struct sockaddr*) &sin, sizeof(struct sockaddr_in));
                    if (ret == SOCKET_ERROR) {
                        AJ_ErrPrintf(("AJ_Net_SendTo(): sendto() failed (IPV4). WSAGetLastError()=0x%x\n", WSAGetLastError()));
                    } else {
                        ++numWrites;
                    }
                }

                // try sending IPv4 subnet broadcast
                if (family == AF_INET && McastSocks[i].v4_bcast.s_addr) {
                    struct sockaddr_in bsin;
                    memset(&bsin, 0, sizeof(bsin));
                    bsin.sin_family = AF_INET;
                    bsin.sin_port = htons(AJ_UDP_PORT);
                    bsin.sin_addr.s_addr = McastSocks[i].v4_bcast.s_addr;
                    ret = sendto(sock, buf->readPtr, tx, 0, (struct sockaddr*) &bsin, sizeof(struct sockaddr_in));
                    if (ret == SOCKET_ERROR) {
                        AJ_ErrPrintf(("AJ_Net_SendTo(): sendto() failed (bcast). WSAGetLastError()=0x%x\n", WSAGetLastError()));
                    } else {
                        ++numWrites;
                    }
                }
            }

            if ((buf->flags & AJ_IO_BUF_MDNS) && McastSocks[i].is_mdns) {

                // Update the packet with receiver info for this socket
                if (RewriteSenderInfo(buf, ntohl(McastSocks[i].v4_addr.s_addr), McastSocks[i].recv_port) != AJ_OK) {
                    AJ_WarnPrintf(("AJ_Net_SendTo(): RewriteSenderInfo failed.\n"));
                    continue;
                }
                tx = AJ_IO_BUF_AVAIL(buf);

                // try sending IPv4 multicast
                if (family == AF_INET && McastSocks[i].has_mcast4) {
                    struct sockaddr_in sin;
                    memset(&sin, 0, sizeof(sin));
                    sin.sin_family = AF_INET;
                    sin.sin_port = htons(MDNS_UDP_PORT);
                    inet_pton(AF_INET, MDNS_IPV4_MULTICAST_GROUP, &sin.sin_addr);

                    ret = sendto(sock, buf->readPtr, tx, 0, (struct sockaddr*) &sin, sizeof(struct sockaddr_in));
                    if (ret == SOCKET_ERROR) {
                        AJ_ErrPrintf(("AJ_Net_SendTo(): sendto() multicast failed (IPV4). WSAGetLastError()=0x%x\n", WSAGetLastError()));
                    } else {
                        ++numWrites;
                    }
                }

                // try sending IPv4 subnet broadcast
                if (family == AF_INET && McastSocks[i].v4_bcast.s_addr) {
                    struct sockaddr_in bsin;
                    memset(&bsin, 0, sizeof(bsin));
                    bsin.sin_family = AF_INET;
                    bsin.sin_port = htons(MDNS_UDP_PORT);
                    bsin.sin_addr.s_addr = McastSocks[i].v4_bcast.s_addr;
                    ret = sendto(sock, buf->readPtr, tx, 0, (struct sockaddr*) &bsin, sizeof(struct sockaddr_in));
                    if (ret == SOCKET_ERROR) {
                        AJ_ErrPrintf(("AJ_Net_SendTo(): sendto() broadcast failed. WSAGetLastError()=0x%x\n", WSAGetLastError()));
                    } else {
                        ++numWrites;
                    }
                }

                // try sending IPv6 multicast
                if (family == AF_INET6) {
                    struct sockaddr_in6 sin6;
                    memset(&sin6, 0, sizeof(struct sockaddr_in6));
                    sin6.sin6_family = AF_INET6;
                    sin6.sin6_port = htons(MDNS_UDP_PORT);
                    inet_pton(AF_INET6, MDNS_IPV6_MULTICAST_GROUP, &sin6.sin6_addr);
                    ret = sendto(sock, buf->readPtr, tx, 0, (struct sockaddr*) &sin6, sizeof(struct sockaddr_in6));
                    if (ret == SOCKET_ERROR) {
                        AJ_ErrPrintf(("AJ_Net_SendTo(): sendto() failed (IPV6). WSAGetLastError()=0x%x\n", WSAGetLastError()));
                    } else {
                        ++numWrites;
                    }
                }
            }
        }

        if (numWrites == 0) {
            AJ_ErrPrintf(("AJ_Net_SendTo(): Did not sendto() at least one socket.  status=AJ_ERR_WRITE\n"));
            return AJ_ERR_WRITE;
        }
        buf->readPtr += ret;
    }
    AJ_IO_BUF_RESET(buf);
    AJ_InfoPrintf(("AJ_Net_SendTo(): status=AJ_OK\n"));
    return AJ_OK;
}
Exemplo n.º 16
0
static AJ_Status RewriteSenderInfo(AJ_IOBuffer* buf, uint32_t addr, uint16_t port)
{
    size_t tx = AJ_IO_BUF_AVAIL(buf);
    uint16_t sidVal;
    const char send[4] = { 'd', 'n', 'e', 's' };
    const char sid[] = { 's', 'i', 'd', '=' };
    const char ipv4[] = { 'i', 'p', 'v', '4', '=' };
    const char upcv4[] = { 'u', 'p', 'c', 'v', '4', '=' };
    char sidStr[6];
    char ipv4Str[17];
    char upcv4Str[6];
    uint8_t* pkt;
    uint16_t dataLength;
    int match;
    AJ_Status status;

    // first, pluck the search ID from the mDNS header
    sidVal = *(buf->readPtr) << 8;
    sidVal += *(buf->readPtr + 1);

    // convert to strings
    status = AJ_IntToString((int32_t) sidVal, sidStr, sizeof(sidStr));
    if (status != AJ_OK) {
        return AJ_ERR_WRITE;
    }
    status = AJ_IntToString((int32_t) port, upcv4Str, sizeof(upcv4Str));
    if (status != AJ_OK) {
        return AJ_ERR_WRITE;
    }
    status = AJ_InetToString(addr, ipv4Str, sizeof(ipv4Str));
    if (status != AJ_OK) {
        return AJ_ERR_WRITE;
    }

    // ASSUMPTIONS: sender-info resource record is the final resource record in the packet.
    // sid, ipv4, and upcv4 key value pairs are the final three key/value pairs in the record.
    // The length of the other fields in the record are static.
    //
    // search backwards through packet to find the start of "sender-info"
    pkt = buf->writePtr;
    match = 0;
    do {
        if (*(pkt--) == send[match]) {
            match++;
        } else {
            match = 0;
        }
    } while (pkt != buf->readPtr && match != 4);
    if (match != 4) {
        return AJ_ERR_WRITE;
    }

    // move forward to the Data Length field
    pkt += 22;

    // actual data length is the length of the static values already in the buffer plus
    // the three dynamic key-value pairs to re-write
    dataLength = 23 + 1 + sizeof(sid) + strlen(sidStr) + 1 + sizeof(ipv4) + strlen(ipv4Str) + 1 + sizeof(upcv4) + strlen(upcv4Str);
    *pkt++ = (dataLength >> 8) & 0xFF;
    *pkt++ = dataLength & 0xFF;

    // move forward past the static key-value pairs
    pkt += 23;

    // ASSERT: must be at the start of "sid="
    assert(*(pkt + 1) == 's');

    // re-write new values
    *pkt++ = sizeof(sid) + strlen(sidStr);
    memcpy(pkt, sid, sizeof(sid));
    pkt += sizeof(sid);
    memcpy(pkt, sidStr, strlen(sidStr));
    pkt += strlen(sidStr);

    *pkt++ = sizeof(ipv4) + strlen(ipv4Str);
    memcpy(pkt, ipv4, sizeof(ipv4));
    pkt += sizeof(ipv4);
    memcpy(pkt, ipv4Str, strlen(ipv4Str));
    pkt += strlen(ipv4Str);

    *pkt++ = sizeof(upcv4) + strlen(upcv4Str);
    memcpy(pkt, upcv4, sizeof(upcv4));
    pkt += sizeof(upcv4);
    memcpy(pkt, upcv4Str, strlen(upcv4Str));
    pkt += strlen(upcv4Str);

    buf->writePtr = pkt;

    return AJ_OK;
}
Exemplo n.º 17
0
AJ_Status AJ_UnmarshalRaw(AJ_Message* msg, const void** data, size_t len, size_t* actual)
{
    AJ_Status status;
    size_t sz;
    AJ_IOBuffer* ioBuf = &msg->bus->sock.rx;

    /*
     * A soon as we start marshaling raw the header will become invalid so NULL it out
     */
    if (msg->hdr) {
        uint8_t typeId = msg->signature[msg->sigOffset];
        uint8_t pad;
        /*
         * There must be arguments to unmarshal
         */
        if (!typeId) {
            return AJ_ERR_SIGNATURE;
        }
        /*
         * There may be padding before the argument
         */
        pad = PadForType(typeId, ioBuf);
        if (pad > msg->bodyBytes) {
            return AJ_ERR_UNMARSHAL;
        }
        LoadBytes(ioBuf, 0, pad);
        msg->bodyBytes -= pad;
        /*
         * Standard signature matching is now meaningless
         */
        msg->signature = "";
        msg->sigOffset = 0;
        msg->hdr = NULL;
    }
    /*
     * Return an error if caller is attempting read off the end of the body
     */
    if (len > msg->bodyBytes) {
        return AJ_ERR_UNMARSHAL;
    }
    /*
     * We want to return the requested data as contiguous bytes if possible
     */
    sz = AJ_IO_BUF_AVAIL(ioBuf);
    if (sz < len) {
        AJ_IOBufRebase(ioBuf);
    }
    /*
     * If we try to load more than the buffer size we will get an error
     */
    status = LoadBytes(ioBuf, (uint16_t)min(len, ioBuf->bufSize), 0);
    if (status == AJ_OK) {
        sz = AJ_IO_BUF_AVAIL(ioBuf);
        if (sz < len) {
            len = sz;
        }
        *data = ioBuf->readPtr;
        *actual = len;
        ioBuf->readPtr += len;
        msg->bodyBytes -= (uint16_t)len;
    }
    return status;
}
Exemplo n.º 18
0
AJ_Status AJ_UnmarshalMsg(AJ_BusAttachment* bus, AJ_Message* msg, uint32_t timeout)
{
    AJ_Status status;
    AJ_IOBuffer* ioBuf = &bus->sock.rx;
    uint8_t* endOfHeader;
    uint32_t hdrPad;
    /*
     * Clear message then set the bus
     */
    memset(msg, 0, sizeof(AJ_Message));
    msg->msgId = AJ_INVALID_MSG_ID;
    msg->bus = bus;
    /*
     * Move any unconsumed data to the start of the I/O buffer
     */
    AJ_IOBufRebase(ioBuf);
    /*
     * Load the message header
     */
    while (AJ_IO_BUF_AVAIL(ioBuf) < sizeof(AJ_MsgHeader)) {
        //#pragma calls = AJ_Net_Recv
        status = ioBuf->recv(ioBuf, sizeof(AJ_MsgHeader) - AJ_IO_BUF_AVAIL(ioBuf), timeout);
        if (status != AJ_OK) {
            /*
             * If there were no messages to receive check if we have any methods call that have
             * timed-out and if so generate an internal error message to allow the application to
             * proceed.
             */
            if ((status == AJ_ERR_TIMEOUT) && AJ_TimedOutMethodCall(msg)) {
                msg->hdr = (AJ_MsgHeader*)&internalErrorHdr;
                msg->error = AJ_ErrTimeout;
                msg->sender = AJ_GetUniqueName(msg->bus);
                msg->destination = msg->sender;
                status = AJ_OK;
            }

            return status;
        }
    }
    /*
     * Header was unmarsalled directly into the rx buffer
     */
    msg->hdr = (AJ_MsgHeader*)ioBuf->bufStart;
    ioBuf->readPtr += sizeof(AJ_MsgHeader);
    /*
     * Quick sanity check on the header - unrecoverable error if this check fails
     */
    if ((msg->hdr->endianess != AJ_LITTLE_ENDIAN) && (msg->hdr->endianess != AJ_BIG_ENDIAN)) {
        return AJ_ERR_READ;
    }
    /*
     * Endian swap header info - conventiently they are contiguous in the header
     */
    EndianSwap(msg, AJ_ARG_INT32, &msg->hdr->bodyLen, 3);
    msg->bodyBytes = msg->hdr->bodyLen;
    /*
     * The header is null padded to an 8 bytes boundary
     */
    hdrPad = (8 - msg->hdr->headerLen) & 7;
    /*
     * Load the header
     */
    status = LoadBytes(ioBuf, msg->hdr->headerLen + hdrPad, 0);
    if (status != AJ_OK) {
        return status;
    }
#ifndef NDEBUG
    /*
     * Check that messages are getting closed
     */
    AJ_ASSERT(!currentMsg);
    currentMsg = msg;
#endif
    /*
     * Assume an empty signature
     */
    msg->signature = "";
    /*
     * We have the header in the buffer now we can unmarshal the header fields
     */
    endOfHeader = ioBuf->bufStart + sizeof(AJ_MsgHeader) + msg->hdr->headerLen;
    while (ioBuf->readPtr < endOfHeader) {
        const char* fieldSig;
        uint8_t fieldId;
        AJ_Arg hdrVal;
        /*
         * Custom unmarshal the header field - signature is "(yv)" so starts off with STRUCT aligment.
         */
        status = LoadBytes(ioBuf, 4, PadForType(AJ_ARG_STRUCT, ioBuf));
        if (status != AJ_OK) {
            break;
        }
        fieldId = ioBuf->readPtr[0];
        fieldSig = (const char*)&ioBuf->readPtr[2];
        ioBuf->readPtr += 4;
        /*
         * Now unmarshal the field value
         */
        status = Unmarshal(msg, &fieldSig, &hdrVal);
        if (status != AJ_OK) {
            break;
        }
        /*
         * Check the field has the type we expect - we ignore fields we don't know
         */
        if ((fieldId <= AJ_HDR_SESSION_ID) && (TypeForHdr[fieldId] != hdrVal.typeId)) {
            status = AJ_ERR_UNMARSHAL;
            break;
        }
        /*
         * Set the field value in the message
         */
        switch (fieldId) {
        case AJ_HDR_OBJ_PATH:
            msg->objPath = hdrVal.val.v_objPath;
            break;

        case AJ_HDR_INTERFACE:
            msg->iface = hdrVal.val.v_string;
            break;

        case AJ_HDR_MEMBER:
            msg->member = hdrVal.val.v_string;
            break;

        case AJ_HDR_ERROR_NAME:
            msg->error = hdrVal.val.v_string;
            break;

        case AJ_HDR_REPLY_SERIAL:
            msg->replySerial = *(hdrVal.val.v_uint32);
            break;

        case AJ_HDR_DESTINATION:
            msg->destination = hdrVal.val.v_string;
            break;

        case AJ_HDR_SENDER:
            msg->sender = hdrVal.val.v_string;
            break;

        case AJ_HDR_SIGNATURE:
            msg->signature = hdrVal.val.v_signature;
            break;

        case AJ_HDR_TIMESTAMP:
            msg->timestamp = *(hdrVal.val.v_uint32);
            break;

        case AJ_HDR_TIME_TO_LIVE:
            msg->ttl = *(hdrVal.val.v_uint32);
            break;

        case AJ_HDR_SESSION_ID:
            msg->sessionId = *(hdrVal.val.v_uint32);
            break;

        case AJ_HDR_HANDLES:
        case AJ_HDR_COMPRESSION_TOKEN:
        default:
            /* Ignored */
            break;
        }
    }
    if (status == AJ_OK) {
        AJ_ASSERT(ioBuf->readPtr == endOfHeader);
        /*
         * Consume the header pad bytes.
         */
        ioBuf->readPtr += hdrPad;
        /*
         * If the message is encrypted load the entire message body and decrypt it.
         */
        if (msg->hdr->flags & AJ_FLAG_ENCRYPTED) {
            status = LoadBytes(ioBuf, msg->hdr->bodyLen, 0);
            if (status == AJ_OK) {
                status = DecryptMessage(msg);
            }
        }
        /*
         * Toggle the AUTO_START flag so in the API no flags == 0
         *
         * Note we must do this after decrypting the message or message authentication will fail.
         */
        msg->hdr->flags ^= AJ_FLAG_AUTO_START;
        /*
         * If the message looks good try to identify it.
         */
        if (status == AJ_OK) {
            status = AJ_IdentifyMessage(msg);
        }
    } else {
        /*
         * Consume entire header
         */
        ioBuf->readPtr = endOfHeader + hdrPad;
    }
    if (status == AJ_OK) {
        AJ_DumpMsg("RECEIVED", msg, FALSE);
    } else {
        /*
         * Silently discard message unless in debug mode
         */
        AJ_ErrPrintf(("Discarding bad message %s\n", AJ_StatusText(status)));
        AJ_DumpMsg("DISCARDING", msg, FALSE);
        AJ_CloseMsg(msg);
    }

    return status;
}