Changeset 70


Ignore:
Timestamp:
Sep 11, 2007, 8:16:50 PM (18 years ago)
Author:
Yuri Dario
Message:

Implemented automatic reconnection if pipe closes. Fixes ticket:32.

Location:
trunk/samba/source/ndpsmb
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/samba/source/ndpsmb/ndpsmb.c

    r48 r70  
    508508        smb_request req = {0};
    509509        smb_response resp = {0};
     510        char* mem;
     511
    510512        if (!pConn)
    511513        {
     
    513515        }
    514516        log("checkconnection pconnrc %d pipe %d\n", pConn->rc, pConn->pipe);
     517        // YD this code need probably to be removed (reworked), since DosQueryNPHState,
     518        // DosQueryNPipeInfo, DosPeekNPipe, DosResetBuffer, are all returning
     519        // NO_ERROR even if the other pipe end is closed (smbcd crash).
     520        //
     521        // YD TODO probably checkconnection() call can be removed since we
     522        // detect broken pipes inside _DosTransactNPipe
    515523        if (!pConn->rc)
    516524        {
     
    537545                return ERROR_PIPE_NOT_CONNECTED;
    538546        }
     547
     548        // if we are reconnecting pipe because of a broken pipe, we
     549        // need to save shared memory content to allow operation retry
     550        mem = malloc( pConn->pRes->memlen);
     551        if (mem)
     552                memcpy( mem, pConn->mem, pConn->pRes->memlen);
     553
     554        // reinit connection 
    539555        do {
    540556                req.request = SMBREQ_INIT;
     
    554570                        break;
    555571                }
    556 
    557572                MemCpy(pConn->mem, &pConn->srv, sizeof(pConn->srv));
     573
    558574                req.request = SMBREQ_CONNECT;
    559575                req.param = pConn->mem;
     
    568584                }
    569585                MemCpy(&pConn->srv, pConn->mem, sizeof(pConn->srv));
     586
    570587                rc = NO_ERROR;
    571588        } while (0);
    572589
     590        // if we are reconnecting pipe because of a broken pipe, we
     591        // need to restore shared memory content to allow operation retry
     592        if (mem) {
     593                memcpy( pConn->mem, mem, pConn->pRes->memlen);
     594                free( mem);
     595        }
     596
    573597        if (pConn->rc && pConn->pipe)
    574598        {
     
    576600                pConn->pipe = 0;
    577601        }
     602        return rc;
     603}
     604
     605/*
     606 * YD Since DosQueryNPHState,
     607 * DosQueryNPipeInfo, DosPeekNPipe, DosResetBuffer, are all returning
     608 * NO_ERROR even if the other pipe end is closed (smbcd crash),
     609 * we can detect broken pipes only when writing/reading from the pipe.
     610*/
     611ULONG APIENTRY _DosTransactNPipe(Connection *pConn, PVOID pOutbuf, ULONG ulOutbufLength,
     612    PVOID pInbuf, ULONG ulInbufLength, PULONG pulBytesRead)
     613{
     614        APIRET rc;
     615
     616        // try first
     617        rc = DosTransactNPipe(pConn->pipe, pOutbuf, ulOutbufLength, pInbuf, ulInbufLength, pulBytesRead);
     618        if (rc != ERROR_BROKEN_PIPE)
     619                return rc;
     620        // client daemon closed, force open connection again
     621        pConn->rc = rc;
     622        checkconnection( pConn);
     623        // issue command again
     624        rc = DosTransactNPipe(pConn->pipe, pOutbuf, ulOutbufLength, pInbuf, ulInbufLength, pulBytesRead);
    578625        return rc;
    579626}
     
    681728                        req.paramlen = 0;
    682729
    683                         DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
     730                        rc = _DosTransactNPipe(pConn, &req, sizeof(req), &resp, sizeof(resp), &action);
    684731
    685732                        req.request = SMBREQ_CONNECT;
     
    688735                        req.paramlen = sizeof(pConn->srv);
    689736
    690                         rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
     737                        rc = _DosTransactNPipe(pConn, &req, sizeof(req), &resp, sizeof(resp), &action);
    691738                        if (rc || action < sizeof(resp) || resp.rc)
    692739                        {
     740                                APIRET rc2;
    693741                                rc = rc ? rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
    694742                                MemCpy(tmp, &pRes->srv, sizeof(pRes->srv));
    695                                 DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
     743                                rc2 = _DosTransactNPipe(pConn, &req, sizeof(req), &resp, sizeof(resp), &action);
    696744                                // TODO: what to do if the reconnect will fail ?
    697745                        }
     
    790838                req.request = SMBREQ_INIT;
    791839                req.param = (char *)0xFFFFFFFF;
    792                 rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
     840                rc = _DosTransactNPipe(pConn, &req, sizeof(req), &resp, sizeof(resp), &action);
    793841                if (rc || action < sizeof(resp) || resp.rc)
    794842                {
     
    815863                req.length = req.paramlen;
    816864
    817                 rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
     865                rc = _DosTransactNPipe(pConn, &req, sizeof(req), &resp, sizeof(resp), &action);
    818866                if (rc || action < sizeof(resp) || resp.rc)
    819867                {
     
    865913                        req.paramlen = sizeof(pConn->file);
    866914
    867                         DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
     915                        _DosTransactNPipe(pConn, &req, sizeof(req), &resp, sizeof(resp), &action);
    868916                        pConn->file.fd = -1;
    869917                }
     
    874922                req.paramlen = 0;
    875923
    876                 DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
     924                _DosTransactNPipe(pConn, &req, sizeof(req), &resp, sizeof(resp), &action);
    877925
    878926                DosFreeMem(pConn->mem);
     
    10801128                do {
    10811129                        int i;
    1082                         pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
     1130                        pConn->rc = _DosTransactNPipe(pConn, &req, sizeof(req), &resp, sizeof(resp), &action);
    10831131                        if (pConn->rc || action < sizeof(resp)
    10841132                                || (resp.rc && resp.rc != ERROR_MORE_DATA))
     
    11771225                req.paramlen = sizeof(*finfo);
    11781226                req.length = req.paramlen;
    1179                 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
     1227                pConn->rc = _DosTransactNPipe(pConn, &req, sizeof(req), &resp, sizeof(resp), &action);
    11801228                if (pConn->rc || action < sizeof(resp) || resp.rc)
    11811229                {
     
    12181266                        {
    12191267                                *p = 0;
    1220                                 rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
     1268                                rc = _DosTransactNPipe(pConn, &req, sizeof(req), &resp, sizeof(resp), &action);
    12211269                                if (pConn->rc || action < sizeof(resp) || resp.rc)
    12221270                                {       
     
    12971345                req.paramlen = sizeof(*finfo);
    12981346                req.length = req.paramlen;
    1299                 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
     1347                pConn->rc = _DosTransactNPipe(pConn, &req, sizeof(req), &resp, sizeof(resp), &action);
    13001348                if (pConn->rc || action < sizeof(resp) || resp.rc)
    13011349                {
     
    14111459                req.length = pRes->memlen - req.paramlen;
    14121460                pFEASrc = (FEALIST *)(pConn->mem + req.paramlen);
    1413                 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
     1461                pConn->rc = _DosTransactNPipe(pConn, &req, sizeof(req), &resp, sizeof(resp), &action);
    14141462                if (pConn->rc || action < sizeof(resp) || resp.rc)
    14151463                {
     
    14921540                req.paramlen = pFEAList->cbList + CCHMAXPATH + 1;
    14931541                req.length = req.paramlen;
    1494                 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
     1542                pConn->rc = _DosTransactNPipe(pConn, &req, sizeof(req), &resp, sizeof(resp), &action);
    14951543                if (pConn->rc || action < sizeof(resp) || resp.rc)
    14961544                {
     
    15561604                req.length = pRes->memlen - req.paramlen;
    15571605                pfealist = (FEALIST *)(pConn->mem + req.paramlen);
    1558                 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
     1606                pConn->rc = _DosTransactNPipe(pConn, &req, sizeof(req), &resp, sizeof(resp), &action);
    15591607                if (pConn->rc || action < sizeof(resp) || resp.rc)
    15601608                {
     
    16121660                req.paramlen = CCHMAXPATH + 1;
    16131661                req.length = req.paramlen;
    1614                 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
     1662                pConn->rc = _DosTransactNPipe(pConn, &req, sizeof(req), &resp, sizeof(resp), &action);
    16151663                if (pConn->rc || action < sizeof(resp) || resp.rc)
    16161664                {
     
    16631711                req.paramlen = CCHMAXPATH + 1;
    16641712                req.length = req.paramlen;
    1665                 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
     1713                pConn->rc = _DosTransactNPipe(pConn, &req, sizeof(req), &resp, sizeof(resp), &action);
    16661714                if (pConn->rc || action < sizeof(resp) || resp.rc)
    16671715                {
     
    17021750                req.paramlen = CCHMAXPATH + 1;
    17031751                req.length = req.paramlen;
    1704                 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
     1752                pConn->rc = _DosTransactNPipe(pConn, &req, sizeof(req), &resp, sizeof(resp), &action);
    17051753                if (pConn->rc || action < sizeof(resp) || resp.rc)
    17061754                {
     
    17411789                req.paramlen = CCHMAXPATH + 1;
    17421790                req.length = req.paramlen;
    1743                 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
     1791                pConn->rc = _DosTransactNPipe(pConn, &req, sizeof(req), &resp, sizeof(resp), &action);
    17441792                if (pConn->rc || action < sizeof(resp) || resp.rc)
    17451793                {
     
    17961844                req.paramlen = 2 * (CCHMAXPATH + 1);
    17971845                req.length = req.paramlen;
    1798                 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
     1846                pConn->rc = _DosTransactNPipe(pConn, &req, sizeof(req), &resp, sizeof(resp), &action);
    17991847                if (pConn->rc || action < sizeof(resp) || resp.rc)
    18001848                {
     
    18711919                req.paramlen = sizeof(pConn->file);
    18721920                req.length = req.paramlen;
    1873                 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
     1921                pConn->rc = _DosTransactNPipe(pConn, &req, sizeof(req), &resp, sizeof(resp), &action);
    18741922                if (pConn->rc || action < sizeof(resp) || resp.rc)
    18751923                {
     
    19511999                req.paramlen = sizeof(*finfo);
    19522000                req.length = req.paramlen;
    1953                 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
     2001                pConn->rc = _DosTransactNPipe(pConn, &req, sizeof(req), &resp, sizeof(resp), &action);
    19542002                if (pConn->rc || action < sizeof(resp) || resp.rc)
    19552003                {
     
    20032051                req.paramlen = sizeof(pConn->file);
    20042052                req.length = req.paramlen + sizeof(*finfo);
    2005                 rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
     2053                rc = _DosTransactNPipe(pConn, &req, sizeof(req), &resp, sizeof(resp), &action);
    20062054                if (pConn->rc || action < sizeof(resp) || resp.rc)
    20072055                {
     
    20652113                req.length = pRes->memlen - req.paramlen;
    20662114                pFEASrc = (FEALIST *)(pConn->mem + req.paramlen);
    2067                 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
     2115                pConn->rc = _DosTransactNPipe(pConn, &req, sizeof(req), &resp, sizeof(resp), &action);
    20682116                if (pConn->rc || action < sizeof(resp) || resp.rc)
    20692117                {
     
    21392187                req.length = req.paramlen;
    21402188
    2141                 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
     2189                pConn->rc = _DosTransactNPipe(pConn, &req, sizeof(req), &resp, sizeof(resp), &action);
    21422190                if (pConn->rc || action < sizeof(resp) || resp.rc)
    21432191                {
     
    21882236                req.length = pRes->memlen - req.paramlen;
    21892237                pfealist = (FEALIST *)(pConn->mem + req.paramlen);
    2190                 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
     2238                pConn->rc = _DosTransactNPipe(pConn, &req, sizeof(req), &resp, sizeof(resp), &action);
    21912239                if (pConn->rc || action < sizeof(resp) || resp.rc)
    21922240                {
     
    22832331                req.paramlen = sizeof(pConn->file) + sizeof(long) + sizeof(long long);
    22842332                req.length = req.paramlen;
    2285                 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
     2333                pConn->rc = _DosTransactNPipe(pConn, &req, sizeof(req), &resp, sizeof(resp), &action);
    22862334                if (pConn->rc || action < sizeof(resp) || resp.rc)
    22872335                {
     
    23372385                req.paramlen = sizeof(pConn->file);
    23382386                req.length = req.paramlen;
    2339                 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
     2387                pConn->rc = _DosTransactNPipe(pConn, &req, sizeof(req), &resp, sizeof(resp), &action);
    23402388                if (pConn->rc || action < sizeof(resp) || resp.rc)
    23412389                {
     
    23962444                req.length = req.paramlen;
    23972445
    2398                 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
     2446                pConn->rc = _DosTransactNPipe(pConn, &req, sizeof(req), &resp, sizeof(resp), &action);
    23992447                if (pConn->rc || action < sizeof(resp) || resp.rc)
    24002448                {
     
    24452493                        req.length = req.paramlen + (pRes->memlen - req.paramlen < (ulRead - done) ? pRes->memlen - req.paramlen : (ulRead - done));
    24462494       
    2447                         pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
     2495                        pConn->rc = _DosTransactNPipe(pConn, &req, sizeof(req), &resp, sizeof(resp), &action);
    24482496                        if (pConn->rc || action < sizeof(resp) || resp.rc)
    24492497                        {
     
    25022550                        req.length += req.paramlen;
    25032551
    2504                         pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
     2552                        pConn->rc = _DosTransactNPipe(pConn, &req, sizeof(req), &resp, sizeof(resp), &action);
    25052553                        if (pConn->rc || action < sizeof(resp) || resp.rc)
    25062554                        {
  • trunk/samba/source/ndpsmb/smbcd.c

    r69 r70  
    299299        cli_state * cli = *_cli;
    300300
    301         if (!pipe || !*cli || !reconnect || !srv || !req || !req->param || req->paramlen > req->length || !res)
     301        if (!pipe || !_cli || !reconnect || !srv || !req || !req->param || req->paramlen > req->length || !res)
    302302        {
    303303                debuglocal(0,"invalid structures\n");   
Note: See TracChangeset for help on using the changeset viewer.