Skip to Content.
Sympa Menu

freetds - Re: [freetds] tinytds based on freetds crashing

freetds AT lists.ibiblio.org

Subject: FreeTDS Development Group

List archive

Chronological Thread  
  • From: Krzysztof Chodak <krzysztof.chodak AT gmail.com>
  • To: FreeTDS Development Group <freetds AT lists.ibiblio.org>
  • Subject: Re: [freetds] tinytds based on freetds crashing
  • Date: Thu, 5 Apr 2012 20:30:40 +0200

Seems you are right: I have made a test by sending the same query with
microsoft tools and wireshark reports malformed packet as well so freetds
is as good as microsoft here (or the other way round) :)
I also found two wireshark TDS bug entries so indeed it was not the best
(however very handy) tool to use.
https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=1219
https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=3098
Best regards,
Krzysztof Chodak

On Thu, Apr 5, 2012 at 16:23, Frediano Ziglio <freddy77 AT gmail.com> wrote:

> Oh, don't mind, wireshark are not so updated.
> Server reply to previous request, just closed connection after latest
> request.
> Last request however is correct (language token are very hard to
> malform as it's the easier one and more used)
> It seems relate to some timeout. Router or other stuff could be. Or
> perhaps keepalive is not set correctly by our library. It seems that
> server sent only a keepalive.
>
> Frediano
>
> Il 05 aprile 2012 12:07, Krzysztof Chodak <krzysztof.chodak AT gmail.com>
> ha scritto:
> > That is why I am still saying it.
> > [image: Inline image 1]
> > My first trace was on wire using wireshark and I saw repetitive info like
> > above.
> >
> > On Thu, Apr 5, 2012 at 12:58, Frediano Ziglio <freddy77 AT gmail.com>
> wrote:
> >
> >> Why you keep saying that server report malformed packets ??
> >> Server just drop connection without any notice to client so there is
> >> nothing wrong in capture.
> >>
> >> Frediano
> >>
> >> Il 05 aprile 2012 07:32, Krzysztof Chodak <krzysztof.chodak AT gmail.com>
> >> ha scritto:
> >> > Thanks you James for fruitful analysis.
> >> > (error message when posting zip was:
> >> > "Google tried to deliver your message, but it was rejected by the
> >> > recipient domain. We recommend contacting the other email provider for
> >> > further information about the cause of this error. The error that the
> >> > other server returned was: 550 550 5.7.1 illegal attachment type
> >> > (state 18)."
> >> > As it was 335K it was over the limit)
> >> > Thank you Ken for ticketing and Frediano for a fix.
> >> >
> >> > I would like to catch some more of your attention and get back to my
> >> > first post and probably the core source of the
> >> > problem. Why server is dropping the connection? James - would you be
> >> > so kind to have a look at packets dump I initially posted (captured by
> >> > wireshark,
> >>
> https://docs.google.com/open?id=0B8Pbr6Jr1eaCa1R0NnVfdnpUb1M4a0pVVGl3WEZTZw
> >> )
> >> > and try to check why server is reporting malformed TDS packets? I
> >> > could also try to help but I would need to know where TDS 7.1 protocol
> >> > documentation resides?
> >> >
> >> > On Thu, Apr 5, 2012 at 08:18, Frediano Ziglio <freddy77 AT gmail.com>
> >> wrote:
> >> >> Il giorno 04/apr/2012, alle ore 22:18, "James K. Lowden" <
> >> jklowden AT freetds.org> ha scritto:
> >> >>
> >> >>> On Wed, 4 Apr 2012 13:00:05 +0200
> >> >>> Krzysztof Chodak <krzysztof.chodak AT gmail.com> wrote:
> >> >>>
> >> >>>>> Here it is: TDSDUMP log with a (ruby/tinytds/freetds) crash at the
> >> >>>>> end
> >> >>>>
> >> >>>> list does not like zip attachments so file is placed here:
> >> >>>>
> >>
> https://docs.google.com/open?id=0B8Pbr6Jr1eaCZnFCUDk3LWxTYXVncFpCaUdfdjhIdw
> >> >>>
> >> >>> (What message did you get posting a zip file? It should be
> >> >>> permitted provided it's under 75 KB.)
> >> >>>
> >> >>> The TDSDUMP log clarifies several points.
> >> >>>
> >> >>> FreeTDS 0.91
> >> >>> TDS 7.1
> >> >>> Windows (log file is on C: drive)
> >> >>> client charset is UTF-8 (unusual but OK)
> >> >>>
> >> >>> The trouble starts when the server disconnects unexpectedly. It
> ends
> >> >>> when unbounded recursion caused by the application's error handler
> >> >>> consumes the stack and crashes the process.
> >> >>>
> >> >>> Why the server disconnected isn't clear or even certain. All that
> we
> >> >>> know is that the last write returned "Connection reset by peer",
> which
> >> >>> normally indicates the connection was closed by the remote.
> >> >>>
> >> >>> The last packet sent is on line 81590 of the log file
> >> >>>
> >> >>> SELECT TOP (1) [users].* FROM [users]
> >> >>> WHERE [users].[login] = N''bradoscb''
> >> >>>
> >> >>> Immediately beneath the dumped packet we see
> >> >>>
> >> >>> net.c:667:send(2) failed: 10054
> >> >>> (WSAECONNRESET: Connection reset by peer.)
> >> >>>
> >> >>> which tells us the library detected the OS error. Then
> >> >>>
> >> >>> util.c:331:tdserror(03a04588, 03fe49b0, 20006, 10054)
> >> >>> dblib.c:7929:dbperror(03d32008, 20006, 10054)
> >> >>> dblib.c:7981:20006: "Write to the server failed"
> >> >>>
> >> >>> per normal, then
> >> >>>
> >> >>> dblib.c:5780:dbgetuserdata(03d32008)
> >> >>> dblib.c:5780:dbgetuserdata(03d32008)
> >> >>> dblib.c:4880:dbdead(03d32008) [alive]
> >> >>>
> >> >>> wrong. A disconnected session is anything but alive.
> >> >>>
> >> >>> dblib.c:4639:dbsqlok(03d32008)
> >> >>> dblib.c:4669:dbsqlok() not done, calling tds_process_tokens()
> >> >>>
> >> >>> db-lib still thinks the session is up ...
> >> >>>
> >> >>> token.c:540:tds_process_tokens(03fe49b0, 00226220, 0022621c, 0x6914)
> >> >>> util.c:156:Changed query state from PENDING to READING
> >> >>> util.c:331:tdserror(03a04588, 03fe49b0, 20004, 10054)
> >> >>> dblib.c:7929:dbperror(03d32008, 20004, 10054)
> >> >>> dblib.c:7981:20004: "Read from the server failed"
> >> >>>
> >> >>> but the read failed ...
> >> >>>
> >> >>> dblib.c:5780:dbgetuserdata(03d32008)
> >> >>> dblib.c:5780:dbgetuserdata(03d32008)
> >> >>> dblib.c:4880:dbdead(03d32008) [alive]
> >> >>> dblib.c:4639:dbsqlok(03d32008)
> >> >>> dblib.c:4669:dbsqlok() not done, calling tds_process_tokens()
> >> >>>
> >> >>> and we enter an infinite loop.
> >> >>>
> >> >>> Analysis
> >> >>> ---------
> >> >>>
> >> >>> Windows returns a valid error code WSAECONNRESET. This is reported
> to
> >> >>> the log in tds/net.c:tds_goodwrite() on line 667. That logic closes
> >> >>> the socket and returns -1 to tds_write_packet().
> >> >>>
> >> >>> How did we get there? The log shows
> >> >>>
> >> >>> dblib.c:6862:dbsqlsend(03d32008)
> >> >>> write.c:168:tds_put_string wrote 194 bytes
> >> >>>
> >> >>> tds_put_string() calls
> >> >>> tds_put_n() calls
> >> >>> tds_write_packet
> >> >>>
> >> >>> tds_write_packet() returrns TDS_FAIL to tds_put_n()
> >> >>>
> >> >>> which discards the return code. :-(
> >> >>>
> >> >>> Propogating the error code is not the only way error information is
> >> >>> provided to db-lib from libtds. tds_goodwrite() also calls
> tdserror
> >> >>> (), which calls the client's error handler. We see that in the log,
> >> too
> >> >>>
> >> >>> util.c:331:tdserror(03a04588, 03fe49b0, 20006, 10054)
> >> >>> dblib.c:7929:dbperror(03d32008, 20006, 10054)
> >> >>> dblib.c:7981:20006: "Write to the server failed"
> >> >>>
> >> >>> What we do *not* see in the log is the product of the next line in
> >> >>> tdserror()
> >> >>>
> >> >>> tdsdump_log(TDS_DBG_FUNC,
> >> >>> "tdserror: client library returned %s(%d)\n", retname(rc), rc);
> >> >>>
> >> >>> The missing message in the log indicates the error handler is
> Charlie
> >> on
> >> >>> the MTA: it Never Returned.
> >> >>>
> >> >>> It would appear -- whether by design or not -- that the
> >> >>> client-installed error handler makes db-lib calls, in particular
> >> >>> dbsqlok(). Don't do that. It engenders infinite recursion just
> >> >>> as evinced by the log:
> >> >>>
> >> >>> dblib.c:4669:dbsqlok() not done, calling tds_process_tokens()
> >> >>> token.c:540:tds_process_tokens(03fe49b0, 00226220, 0022621c, 0x6914)
> >> >>> util.c:331:tdserror(03a04588, 03fe49b0, 20004, 10054)
> >> >>> dblib.c:7929:dbperror(03d32008, 20004, 10054)
> >> >>> dblib.c:7981:20004: "Read from the server failed"
> >> >>> # no tdserror message here
> >> >>> # to indicate the handler's return code
> >> >>> ...
> >> >>> dblib.c:4639:dbsqlok(03d32008) # from within handler
> >> >>> dblib.c:4669:dbsqlok() not done, calling tds_process_tokens()
> >> >>>
> >> >>> (It looks like an infinite loop, but it's infinite recursion.
> >> >>> Computationally equivalent constructs, just one is more familar to C
> >> >>> programmers than the other.)
> >> >>>
> >> >>> Incidentally, this would also explain why dbdead() reports
> "[active]".
> >> >>> In tds_goodread(), the socket isn't closed until after tdserror()
> >> >>> returns. Because the socket is still open within the recursion, all
> >> >>> calls to dbdead() continue to find the socket open and it reports
> >> >>> "active".
> >> >>>
> >> >>
> >> >> Fixed in both 0.91 and master!
> >> >>
> >> >>> Give your error handler a nickle and let it return. Otherwise it
> will
> >> >>> eventually devour the stack along with your process.
> >> >>>
> >> >>> --jkl
> >> >>>
> >> >>
> >> >> Frediano
> >> >>
> >> _______________________________________________
> >> FreeTDS mailing list
> >> FreeTDS AT lists.ibiblio.org
> >> http://lists.ibiblio.org/mailman/listinfo/freetds
> >>
> >
> > _______________________________________________
> > FreeTDS mailing list
> > FreeTDS AT lists.ibiblio.org
> > http://lists.ibiblio.org/mailman/listinfo/freetds
> >
> _______________________________________________
> FreeTDS mailing list
> FreeTDS AT lists.ibiblio.org
> http://lists.ibiblio.org/mailman/listinfo/freetds
>




Archive powered by MHonArc 2.6.24.

Top of Page