diff --git a/openbsc/src/libtrau/rtp_proxy.c b/openbsc/src/libtrau/rtp_proxy.c
index 3d34ac6..36629ae 100644
--- a/openbsc/src/libtrau/rtp_proxy.c
+++ b/openbsc/src/libtrau/rtp_proxy.c
@@ -555,12 +555,10 @@ struct rtp_socket *rtp_socket_create(void)
 
 	rc = rtp_socket_bind(rs, INADDR_ANY);
 	if (rc < 0)
-		goto out_rtcp_bfd;
+		goto out_free;
 
 	return rs;
 
-out_rtcp_bfd:
-	osmo_fd_unregister(&rs->rtcp.bfd);
 out_rtcp_socket:
 	close(rs->rtcp.bfd.fd);
 out_rtp_bfd:
@@ -595,39 +593,76 @@ static int rtp_sub_socket_bind(struct rtp_sub_socket *rss, uint32_t ip,
 			   &alen);
 }
 
-#define RTP_PORT_BASE	30000
-static unsigned int next_udp_port = RTP_PORT_BASE;
+#define RTP_PORT_BASE   30000
+#define RTP_PORT_MAX    39998
+#define NEXT_UDP_PORT next_udp_port = (next_udp_port + 2 > RTP_PORT_MAX) ? \
+					RTP_PORT_BASE : next_udp_port + 2
+static unsigned short next_udp_port = RTP_PORT_BASE;
 
 /* bind a RTP socket to a local address */
 int rtp_socket_bind(struct rtp_socket *rs, uint32_t ip)
 {
-	int rc = -EIO;
+	int rc, rc2;
 	struct in_addr ia;
+	unsigned short start_port;
 
 	ia.s_addr = htonl(ip);
 	DEBUGP(DLMUX, "rtp_socket_bind(rs=%p, IP=%s): ", rs,
 		inet_ntoa(ia));
 
 	/* try to bind to a consecutive pair of ports */
-	for (next_udp_port = next_udp_port % 0xffff;
-	     next_udp_port < 0xffff; next_udp_port += 2) {
+	start_port = next_udp_port;
+	while (1) {
 		rc = rtp_sub_socket_bind(&rs->rtp, ip, next_udp_port);
-		if (rc != 0)
-			continue;
+		if (rc < 0)
+			goto try_next_port;
 
 		rc = rtp_sub_socket_bind(&rs->rtcp, ip, next_udp_port+1);
-		if (rc == 0)
+		if (rc == 0) {
+			NEXT_UDP_PORT;
+			next_udp_port = (next_udp_port + 2 > RTP_PORT_MAX) ?
+					RTP_PORT_BASE : next_udp_port + 2;
+			break;
+		}
+		/* reopen rtp socket and try again with next udp port */
+		osmo_fd_unregister(&rs->rtp.bfd);
+		close(rs->rtp.bfd.fd);
+		rs->rtp.bfd.fd = -1;
+		rc2 = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+		if (rc2 < 0) {
+			rc = rc2;
+			goto out_rtp;
+		}
+		init_rss(&rs->rtp, rs, rc2, RTP_PRIV_RTP);
+		rc2 = osmo_fd_register(&rs->rtp.bfd);
+		if (rc2 < 0) {
+			close(rs->rtp.bfd.fd);
+			rc = rc2;
+			goto out_rtp;
+		}
+try_next_port:
+		NEXT_UDP_PORT;
+		if (next_udp_port == start_port)
 			break;
+		/* we must use rc2, in order to preserve rc */
 	}
 	if (rc < 0) {
 		DEBUGPC(DLMUX, "failed\n");
-		return rc;
+		goto out_rtcp;
 	}
 
 	ia.s_addr = rs->rtp.sin_local.sin_addr.s_addr;
 	DEBUGPC(DLMUX, "BOUND_IP=%s, BOUND_PORT=%u\n",
 		inet_ntoa(ia), ntohs(rs->rtp.sin_local.sin_port));
 	return ntohs(rs->rtp.sin_local.sin_port);
+
+out_rtcp:
+	osmo_fd_unregister(&rs->rtcp.bfd);
+	close(rs->rtcp.bfd.fd);
+out_rtp:
+	osmo_fd_unregister(&rs->rtp.bfd);
+	close(rs->rtp.bfd.fd);
+	return rc;
 }
 
 static int rtp_sub_socket_connect(struct rtp_sub_socket *rss,
