ipa: stricter accept callback handling in ipa_server_link_create

Add assertion as suggested by Holger. This function does not make
much sense with the accept callback set. While at it, check return
value of the accept callback and release the peer socket in case
such callback returns an error.

Reported by Holger.

Reference: CID 1040692
diff --git a/src/input/ipa.c b/src/input/ipa.c
index 3abd2b8..d1d863e 100644
--- a/src/input/ipa.c
+++ b/src/input/ipa.c
@@ -307,24 +307,28 @@
 
 static int ipa_server_fd_cb(struct osmo_fd *ofd, unsigned int what)
 {
-	int ret;
+	int fd, ret;
 	struct sockaddr_in sa;
 	socklen_t sa_len = sizeof(sa);
 	struct ipa_server_link *link = ofd->data;
 
-	ret = accept(ofd->fd, (struct sockaddr *)&sa, &sa_len);
-	if (ret < 0) {
+	fd = accept(ofd->fd, (struct sockaddr *)&sa, &sa_len);
+	if (fd < 0) {
 		LOGP(DLINP, LOGL_ERROR, "failed to accept from origin "
 			"peer, reason=`%s'\n", strerror(errno));
-		return ret;
+		return fd;
 	}
 	LOGP(DLINP, LOGL_NOTICE, "accept()ed new link from %s to port %u\n",
 		inet_ntoa(sa.sin_addr), link->port);
 
-	if (link->accept_cb)
-		link->accept_cb(link, ret);
-	else
-		close(ret);
+	ret = link->accept_cb(link, fd);
+	if (ret < 0) {
+		LOGP(DLINP, LOGL_ERROR,
+		     "failed to processs accept()ed new link, "
+		     "reason=`%s'\n", strerror(-ret));
+		close(fd);
+		return ret;
+	}
 
 	return 0;
 }
@@ -337,6 +341,8 @@
 {
 	struct ipa_server_link *ipa_link;
 
+	OSMO_ASSERT(accept_cb != NULL);
+
 	ipa_link = talloc_zero(ctx, struct ipa_server_link);
 	if (!ipa_link)
 		return NULL;