summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_network.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_network.c')
-rw-r--r--bgpd/bgp_network.c78
1 files changed, 59 insertions, 19 deletions
diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c
index 1a10d8ae..3c1cf753 100644
--- a/bgpd/bgp_network.c
+++ b/bgpd/bgp_network.c
@@ -60,6 +60,9 @@ bgp_getsockname(int fd, union sockunion* su_local, union sockunion* su_remote) ;
static int
bgp_socket_set_common_options(int fd, union sockunion* su, int ttl,
const char* password) ;
+static int
+bgp_md5_set_listeners(union sockunion* su, const char* password) ;
+
/*==============================================================================
* Open and close the listeners.
*
@@ -334,16 +337,54 @@ bgp_init_listener(int sock, struct sockaddr *sa, socklen_t salen)
/*------------------------------------------------------------------------------
* Prepare to accept() connection
*
- * Sets session->accept true -- so accept() action will accept the connection.
+ * If the session has a password, then this is where the listener(s) for the
+ * appropriate address family are told about the password.
+ *
+ * This is done shortly before the session is first enabled for accept().
*
+ * The effect is (probably) that the peer's attempts to connect with MD5 signed
+ * packets will simply have been ignored up to this point. From this point
+ * forward they will be accepted, but closed until accept is enabled.
+ *
+ * NB: requires the session mutex LOCKED.
+ */
+extern void
+bgp_prepare_to_accept(bgp_connection connection)
+{
+ int ret ;
+
+ if (connection->session->password != NULL)
+ {
+ ret = bgp_md5_set_listeners(connection->session->su_peer,
+ connection->session->password) ;
+
+/* TODO: failure to set password in bgp_prepare_to_accept ? */
+ } ;
+
+ return ;
+} ;
+
+/*------------------------------------------------------------------------------
+ * No longer prepared to accept() connection
*
+ * If the session has a password, then this is where it is withdrawn from the
+ * listener(s) for the appropriate address family.
*
* NB: requires the session mutex LOCKED.
*/
extern void
-bgp_open_accept(bgp_connection connection)
+bgp_not_prepared_to_accept(bgp_connection connection)
{
+ int ret ;
+
+ if (connection->session->password != NULL)
+ {
+ ret = bgp_md5_set_listeners(connection->session->su_peer, NULL) ;
+
+/* TODO: failure to clear password in bgp_not_prepared_to_accept ? */
+ } ;
+ return ;
} ;
/*------------------------------------------------------------------------------
@@ -420,7 +461,7 @@ bgp_accept_action(qps_file qf, void* file_info)
/* See if we are ready to accept connections from the connecting party */
session = bgp_session_lookup(&su_remote, &exists) ;
- if (bgp_session_is_accepting(session))
+ if (session != NULL)
{
if (BGP_DEBUG(events, EVENTS))
zlog_debug(exists
@@ -501,12 +542,12 @@ bgp_open_connect(bgp_connection connection)
/* Make socket for the connect connection. */
fd = sockunion_socket(su) ;
- if (fd < 0)
- return errno ; /* give up immediately if cannot create socket */
+ ret = (fd >= 0) ? 0 : errno ;
/* Set the common options. */
- ret = bgp_socket_set_common_options(fd, su, connection->session->ttl,
- connection->session->password) ;
+ if (ret == 0)
+ ret = bgp_socket_set_common_options(fd, su, connection->session->ttl,
+ connection->session->password) ;
/* Bind socket. */
if (ret == 0)
@@ -536,7 +577,8 @@ bgp_open_connect(bgp_connection connection)
if (ret != 0)
{
- close(fd) ;
+ if (fd >= 0)
+ close(fd) ;
bgp_fsm_connect_completed(connection, ret, NULL, NULL) ;
@@ -895,29 +937,28 @@ bgp_md5_set_socket(int fd, union sockunion *su, const char *password)
} ;
/*------------------------------------------------------------------------------
- * Set MD5 password for given peer in the listener(s) for the peer's address
- * family.
- *
- * NB: requires the session mutex LOCKED.
+ * Set (or clear) MD5 password for given peer in the listener(s) for the peer's
+ * address family.
*
* This allows system to accept MD5 "signed" incoming connections from the
* given address.
*
+ * NULL password clears the password for the given peer.
+ *
* Returns: 0 => OK
* otherwise: errno -- the first error encountered.
*
* NB: peer address must be AF_INET or (if supported) AF_INET6
*
- * NB: if there are no listeners in the required
+ * NB: does nothing and returns "OK" if there are no listeners in the
+ * address family -- wanting to set MD5 makes no difference to this !
*/
-extern int
-bgp_md5_set_listeners(bgp_connection connection)
+static int
+bgp_md5_set_listeners(union sockunion* su, const char* password)
{
bgp_listener listener ;
int ret ;
- union sockunion* su = connection->session->su_peer ;
-
#ifdef HAVE_IPV6
assert((su->sa.sa_family == AF_INET) || (su->sa.sa_family == AF_INET6)) ;
#else
@@ -928,8 +969,7 @@ bgp_md5_set_listeners(bgp_connection connection)
while (listener != NULL)
{
- ret = bgp_md5_set_socket(qps_file_fd(&listener->qf), su,
- connection->session->password) ;
+ ret = bgp_md5_set_socket(qps_file_fd(&listener->qf), su, password) ;
if (ret != 0)
return ret ;
} ;