Пример #1
0
static ErrorObj*
ldm_clnt_nullproc(CLIENT* const clnt)
{
    struct timeval timeout;
    ErrorObj*       error;

    log_assert(NULL != clnt);

    timeout.tv_sec = 25;        /* RPC default */
    timeout.tv_usec = 0;

    if (clnt_call(clnt, NULLPROC, xdr_void, NULL, xdr_void,
            NULL, timeout) == 0) {
        error = NULL;
    }
    else {
        struct rpc_err rpcErr;

        clnt_geterr(clnt, &rpcErr);

        error = ERR_NEW(rpcErr.re_status, NULL, clnt_errmsg(clnt));
    }

    return error;
}
Пример #2
0
/*
 * Returns the LDM proxy status for a given client failure. Logs the failure.
 *
 * Arguments:
 *      proxy           The LDM proxy data-structure.
 *      name            The name of the failed message or NULL.
 *      info            Metadata on the data-product that couldn't be sent or
 *                      NULL.
 * Returns:
 *      0               Success.
 *      LP_TIMEDOUT     The failure was due to an RPC timeout. "log_start()"
 *                      called iff "name" isn't NULL.
 *      LP_RPC_ERROR    RPC error. "log_start()" called iff "name" isn't NULL.
 */
static LdmProxyStatus
getStatus(
    LdmProxy* const     proxy,
    const char* const   name,
    prod_info* const    info)
{
    LdmProxyStatus      status;
    struct rpc_err      rpcErr;

    clnt_geterr(proxy->clnt, &rpcErr);

    if (0 == rpcErr.re_status) {
        status = 0;
    }
    else {
        if (NULL != name) {
            LOG_START3("%s failure to host \"%s\": %s", name, proxy->host, 
                    clnt_errmsg(proxy->clnt));

            if (NULL != info) {
                LOG_ADD1("Couldn't send product: %s", s_prod_info(NULL, 0,
                            info, ulogIsDebug()));
            }
        }

        status = RPC_TIMEDOUT == rpcErr.re_status
            ? LP_TIMEDOUT
            : LP_RPC_ERROR;
    }

    return status;
}
Пример #3
0
/*
 * Send a product from file-descriptor to clnt using LDM-6 protocol.
 */
static void
send_product_6(CLIENT *clnt, int fd, prod_info *infop)
{
    unsigned size = infop->sz;

    if (size <= max_hereis) {
        /*
         * The file is small enough to be sent in a single HEREIS message.
         */
        void*   buf = (char*)malloc(size);

        udebug("Sending file via HEREIS");

        if (NULL == buf) {
            serror("Couldn't allocate %u bytes for product data", size);
        }
        else {
            ssize_t nread = read(fd, buf, size);

            if(nread != size) {
                serror("Couldn't read %u bytes of data", size);
            }
            else {
                product product;

                product.info = *infop;
                product.data = buf;

                if (NULL == hereis_6(&product, clnt)) {
                    uerror("%s: HEREIS_6 failure: %s",
                        remote, clnt_errmsg(clnt));
                }
            }

            free(buf);
        }
    }
    else {
        /*
         * The file is so large that it must be sent via COMINGSOON/BLKDATA 
         * messages.
         */
        comingsoon_reply_t* reply;
        comingsoon_args     soonArg;

        udebug("Sending file via COMINGSOON/BLKDATA");

        soonArg.infop = infop;
        soonArg.pktsz = size;
        
        reply = comingsoon_6(&soonArg, clnt);

        if (NULL == reply) {
            uerror("%s: COMINGSOON_6 failure: %s", remote, clnt_errmsg(clnt));
        }
        else {
            if (DONT_SEND == *reply) {
                if (ulogIsVerbose() || ulogIsDebug())
                    uinfo("Downstream LDM says don't send: %s",
                        s_prod_info(NULL, 0, infop, ulogIsDebug()));
            }
            else if (0 != *reply) {
                uwarn("Unexpected reply (%s) from downstream LDM: %s",
                    s_prod_info(NULL, 0, infop, ulogIsDebug()));
            }
            else {
                void*   buf = (char*)malloc(size);

                if (NULL == buf) {
                    serror("Couldn't allocate %u bytes for product data", 
                        size);
                }
                else {
                    ssize_t nread = read(fd, buf, size);

                    if(nread != size) {
                        serror("Couldn't read %u bytes of data", size);
                    }
                    else {
                        datapkt packet;

                        packet.signaturep = (signaturet*)&infop->signature;
                        packet.pktnum = 0;
                        packet.data.dbuf_len = size;
                        packet.data.dbuf_val = buf;

                        if (NULL == blkdata_6(&packet, clnt)) {
                            uerror("%s: BLKDATA_6 failure: %s",
                                remote, clnt_errmsg(clnt));
                        }
                    }

                    free(buf);
                }
            }
        }
    }
}
Пример #4
0
static int
ldmsend(CLIENT *clnt,
        prod_class_t* clssp,
        char*       origin,
        int         seq_start,
        int         nfiles,
        char*       filenames[])
{
        int status = 0;
        char *filename;
        int fd;
        struct stat statb;
        prod_info info;
        MD5_CTX *md5ctxp = NULL;

        /*
         * Allocate an MD5 context
         */
        md5ctxp = new_MD5_CTX();
        if(md5ctxp == NULL)
        {
                status = errno;
                serror("new_md5_CTX failed");
                return status;
        }

        status = (*hiya)(clnt, &clssp);

        if(status != 0)
                return status;

        /* These members are constant over the loop. */
        info.origin = origin;
        info.feedtype = clssp->psa.psa_val->feedtype;

        for( info.seqno = seq_start; exitIfDone(1) && nfiles > 0;
                 filenames++, nfiles--, info.seqno++)
        {
                filename = *filenames;
                info.ident = filename;
                /*
                 * ?? This could be the creation time of the file.
                 */
                (void) set_timestamp(&info.arrival);

                /*
                 * Checks 'arrival', 'feedtype', and 'ident'
                 * against what the other guy has said he wants.
                 */
                if(!prodInClass(clssp, &info))
                {
                        uinfo("%s doesn't want %s", remote, filename);
                        continue;       
                }

                fd = open(filename, O_RDONLY, 0);
                if(fd == -1)
                {
                        serror("open: %s", filename);
                        continue;
                }

                if( fstat(fd, &statb) == -1) 
                {
                        serror("fstat: %s", filename);
                        (void) close(fd);
                        continue;
                }

                uinfo("Sending %s, %d bytes", filename, statb.st_size);
                
                /* These members, and seqno, vary over the loop. */
                if(fd_md5(md5ctxp, fd, statb.st_size, info.signature) != 0)
                {
                        (void) close(fd);
                        continue;
                }
                if(lseek(fd, 0, SEEK_SET) == (off_t)-1)
                {
                        serror("rewind: %s", filename);
                        (void) close(fd);
                        continue;
                }

                (void)exitIfDone(1);

                info.sz = (u_int)statb.st_size;

                (*send_product)(clnt, fd, &info);

                (void) close(fd);
        }

        if (exitIfDone(1) && NULL != nullproc &&
                NULL == (*nullproc)(NULL, clnt)) {
            uerror("%s: NULLPROC failure: %s", remote, clnt_errmsg(clnt));

            status = 1;
        }

        free_MD5_CTX(md5ctxp);  
        return status;
}
Пример #5
0
static int
my_hiya_6(CLIENT *clnt, prod_class_t **clsspp)
{
    static hiya_reply_t* reply;
    int                  error;
    
    reply = hiya_6(*clsspp, clnt);

    if (NULL == reply) {
        uerror("%s: HIYA_6 failure: %s", remote, clnt_errmsg(clnt));

        error = ECONNABORTED;
    }
    else {
        switch (reply->code) {
            case OK:
                max_hereis = reply->hiya_reply_t_u.max_hereis;
                error = 0;
                break;

            case SHUTTING_DOWN:
                uerror("%s: LDM shutting down", remote);
                error = ECONNABORTED;
                break;

            case BADPATTERN:
                uerror("%s: Bad product-class pattern", remote);
                error = ECONNABORTED;
                break;

            case DONT_SEND:
                uerror("%s: LDM says don't send", remote);
                error = ECONNABORTED;
                break;

            case RESEND:
                uerror("%s: LDM says resend (ain't gonna happen)", remote);
                error = ECONNABORTED;
                break;

            case RESTART:
                uerror("%s: LDM says restart (ain't gonna happen)", remote);
                error = ECONNABORTED;
                break;

            case REDIRECT:
                uerror("%s: LDM says redirect (ain't gonna happen)", remote);
                error = ECONNABORTED;
                break;

            case RECLASS:
                *clsspp = reply->hiya_reply_t_u.feedPar.prod_class;
                max_hereis = reply->hiya_reply_t_u.feedPar.max_hereis;
                clss_regcomp(*clsspp);
                /* N.B. we use the downstream patterns */
                unotice("%s: reclass: %s",
                        remote, s_prod_class(NULL, 0, *clsspp));
                error = 0;
                break;
        }

        if (!error)
            udebug("max_hereis = %u", max_hereis);
    }

    return error;
}