[asterisk-commits] dlee: branch 10 r374586 - in /branches/10: ./ main/manager.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Oct 5 15:23:18 CDT 2012


Author: dlee
Date: Fri Oct  5 15:23:14 2012
New Revision: 374586

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=374586
Log:
Multiple revisions 374570,374581

........
  r374570 | dlee | 2012-10-05 15:14:41 -0500 (Fri, 05 Oct 2012) | 22 lines
  
  Improve AMI long line error handling
  
  In AMI's parser, when it receives a long line (> 1024 characters), it discards
  that line, but continues to process the message normally.
  
  Typically, this is not a problem because a) who has lines that long and b)
  usually a discarded line results in an invalid message. But if that line is
  specifying an optional field, then the message will be processed, you get a
  'Response: Success', but things don't work the way you expected them to.
  
  This patch changes the behavior when a line-too-long parse error occurs.
  
  * Changes the log message to avoid way-too-long (and truncated anyways) log
    messages
  * Adds a 'parsing' status flag to Response: Success
  * Sets parsing = MESSAGE_LINE_TOO_LONG if, well, a line is too long
  * Responds with an appropriate error if parsing != MESSAGE_OKAY
  
  (closes issue AST-961)
  Reported by: John Bigelow
  Review: https://reviewboard.asterisk.org/r/2142/
........
  r374581 | dlee | 2012-10-05 15:20:28 -0500 (Fri, 05 Oct 2012) | 1 line
  
  I've committed too much. Reverting part of r374570.
........

Merged revisions 374570,374581 from http://svn.asterisk.org/svn/asterisk/branches/1.8

Modified:
    branches/10/   (props changed)
    branches/10/main/manager.c

Propchange: branches/10/
------------------------------------------------------------------------------
Binary property 'branch-1.8-merged' - no diff available.

Modified: branches/10/main/manager.c
URL: http://svnview.digium.com/svn/asterisk/branches/10/main/manager.c?view=diff&rev=374586&r1=374585&r2=374586
==============================================================================
--- branches/10/main/manager.c (original)
+++ branches/10/main/manager.c Fri Oct  5 15:23:14 2012
@@ -1038,6 +1038,11 @@
 	AST_LIST_ENTRY(mansession_session) list;
 };
 
+enum mansession_message_parsing {
+	MESSAGE_OKAY,
+	MESSAGE_LINE_TOO_LONG
+};
+
 /*! \brief In case you didn't read that giant block of text above the mansession_session struct, the
  * \ref struct mansession is named this solely to keep the API the same in Asterisk. This structure really
  * represents data that is different from Manager action to Manager action. The mansession_session pointer
@@ -1048,6 +1053,7 @@
 	struct ast_tcptls_session_instance *tcptls_session;
 	FILE *f;
 	int fd;
+	enum mansession_message_parsing parsing;
 	int write_error:1;
 	struct manager_custom_hook *hook;
 	ast_mutex_t lock;
@@ -4937,8 +4943,9 @@
 	}
 	if (s->session->inlen >= maxlen) {
 		/* no crlf found, and buffer full - sorry, too long for us */
-		ast_log(LOG_WARNING, "Dumping long line with no return from %s: %s\n", ast_inet_ntoa(s->session->sin.sin_addr), src);
+		ast_log(LOG_WARNING, "Discarding message from %s. Line too long: %.25s...\n", ast_inet_ntoa(s->session->sin.sin_addr), src);
 		s->session->inlen = 0;
+		s->parsing = MESSAGE_LINE_TOO_LONG;
 	}
 	res = 0;
 	while (res == 0) {
@@ -4993,6 +5000,23 @@
 	}
 	ao2_unlock(s->session);
 	return res;
+}
+
+/*!
+ * \internal
+ * \brief Error handling for sending parse errors. This function handles locking, and clearing the
+ * parse error flag.
+ *
+ * \param s AMI session to process action request.
+ * \param m Message that's in error.
+ * \param error Error message to send.
+ */
+static void handle_parse_error(struct mansession *s, struct message *m, char *error)
+{
+	mansession_lock(s);
+	astman_send_error(s, m, error);
+	s->parsing = MESSAGE_OKAY;
+	mansession_unlock(s);
 }
 
 /*!
@@ -5048,7 +5072,15 @@
 					mansession_unlock(s);
 					res = 0;
 				} else {
-					res = process_message(s, &m) ? -1 : 0;
+					switch (s->parsing) {
+					case MESSAGE_OKAY:
+						res = process_message(s, &m) ? -1 : 0;
+						break;
+					case MESSAGE_LINE_TOO_LONG:
+						handle_parse_error(s, &m, "Failed to parse message: line too long");
+						res = 0;
+						break;
+					}
 				}
 				break;
 			} else if (m.hdrcount < ARRAY_LEN(m.headers)) {




More information about the asterisk-commits mailing list