[asterisk-commits] rizzo: branch rizzo/astobj2 r47927 - /team/rizzo/astobj2/channels/chan_sip.c

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Wed Nov 22 06:21:19 MST 2006


Author: rizzo
Date: Wed Nov 22 07:21:18 2006
New Revision: 47927

URL: http://svn.digium.com/view/asterisk?view=rev&rev=47927
Log:
- document more the existing registration states.
  Make use of REG_STATE_NOAUTH, while REG_STATE_TIMEOUT is
  still unused, and i am not sure if there is a reason to use it.
 
- move do_register_auth() inline in the only place where it is
  used (handle_response_register() for 401 and 407).
  This allows for simplifications and also removing what i
  think is a bug - the outcome of transmit_register() should
  not impact the evolution of the session. In the code currently
  in trunk, a failure in transmitting the packet causes the
  destruction of the dialog, which is probably not what we want 
  as we then fail to match replies and never move to 'registered'


Modified:
    team/rizzo/astobj2/channels/chan_sip.c

Modified: team/rizzo/astobj2/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/rizzo/astobj2/channels/chan_sip.c?view=diff&rev=47927&r1=47926&r2=47927
==============================================================================
--- team/rizzo/astobj2/channels/chan_sip.c (original)
+++ team/rizzo/astobj2/channels/chan_sip.c Wed Nov 22 07:21:18 2006
@@ -1194,15 +1194,29 @@
 		/* Initial state. We should have a timeout scheduled for the initial
 		 * (or next) registration transmission, calling sip_reregister
 		 */
+
 	REG_STATE_REGSENT,	/*!< Registration request sent */
 		/* sent initial request, waiting for an ack or a timeout to
 		 * retransmit the initial request.
 		 */
+
 	REG_STATE_AUTHSENT,	/*!< We have tried to authenticate */
+		/* entered after transmit_register with auth info,
+		 * waiting for an ack.
+		 */
+
 	REG_STATE_REGISTERED,	/*!< Registred and done */
 	REG_STATE_REJECTED,	/*!< Registration rejected */
+		/* only used when the remote party has an expire larger than
+		 * our max-expire. This is a final state from which we do not
+		 * recover (not sure how correctly).
+		 */
 	REG_STATE_TIMEOUT,	/*!< Registration timed out */
+		/* XXX unused */
+
 	REG_STATE_NOAUTH,	/*!< We have no accepted credentials */
+		/* fatal - no chance to proceed */
+
 	REG_STATE_FAILED,	/*!< Registration failed after several tries */
 		/* fatal - no chance to proceed */
 };
@@ -7382,8 +7396,8 @@
 }
 
 /*! \brief Registration timeout, register again.
- * Registered as a timeout handler during transmit_register(), but not always
- * (e.g. not on the auth case).
+ * Registered as a timeout handler during transmit_register(),
+ * to retransmit the packet if a reply does not come back.
  * This is called by the scheduler so the event is not pending anymore when
  * we are called.
  */
@@ -7489,7 +7503,7 @@
 			}
 			r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r);
 			r->regattempts++;
-			return 0;
+			return 0;	/* non fatal error */
 		}
 		/* Copy back Call-ID in case create_addr changed it */
 		ast_string_field_set(r, callid, p->callid);
@@ -11448,30 +11462,6 @@
 	return RESULT_SUCCESS;
 }
 
-/*! \brief Authenticate for outbound registration */
-static int do_register_auth(struct sip_pvt *p, struct sip_request *req, enum sip_auth_type code)
-{
-	char *header, *respheader;
-	char digest[1024];
-
-	p->authtries++;
-	auth_headers(code, &header, &respheader);
-	memset(digest,0,sizeof(digest));
-	if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) {
-		/* There's nothing to use for authentication */
- 		/* No digest challenge in request */
- 		if (sip_debug_test_pvt(p) && p->registry)
- 			ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname);
- 			/* No old challenge */
-		return -1;
-	}
-	if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
-		append_history(p, "RegistryAuth", "Try: %d", p->authtries);
- 	if (sip_debug_test_pvt(p) && p->registry)
- 		ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname);
-	return transmit_register(p->registry, digest, respheader); 
-}
-
 /*! \brief Add authentication on outbound SIP packet */
 static int do_proxy_auth(struct sip_pvt *p, struct sip_request *req, enum sip_auth_type code, int sipmethod, int init)
 {
@@ -12362,11 +12352,31 @@
 		 * This is the only case where it makes sense to keep the old
 		 * dialog. In all other cases, we don't need it anymore.
 		 */
-		if (p->authtries == MAX_AUTHTRIES || do_register_auth(p, req, resp)) {
-			ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", r->username, r->hostname, p->authtries);
-			r->register_pvt = pvt_unref(r->register_pvt);	/* don't care anymore */
-			set_destroy(p);
-		}
+		if (p->authtries++ < MAX_AUTHTRIES) {
+			char *header, *respheader;
+			char digest[1024];
+
+			auth_headers(resp, &header, &respheader);	/* select the right headers */
+			memset(digest,0,sizeof(digest));
+			if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) {
+				/* There's nothing to use for authentication, sorry... */
+				/* No digest challenge in request */
+				if (sip_debug_test_pvt(p))
+					ast_verbose("No authentication challenge, giving up for %s\n", r->hostname);
+			} else {
+				/* ok, log events, send the packet and be done */
+				if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
+					append_history(p, "RegistryAuth", "Try: %d", p->authtries);
+				if (sip_debug_test_pvt(p))
+					ast_verbose("Responding to challenge, registration to domain/host name %s\n", r->hostname);
+				transmit_register(r, digest, respheader); 
+				break;
+			}
+		}
+		r->regstate = REG_STATE_NOAUTH;
+		ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", r->username, r->hostname, p->authtries);
+		r->register_pvt = pvt_unref(r->register_pvt);	/* don't care anymore */
+		set_destroy(p);
 		break;
 
 	case 403:	/* Forbidden */



More information about the asterisk-commits mailing list