make clientwr not try to connect (left to reader), changed some timing stuff, issue...
[libradsec.git] / tcp.c
diff --git a/tcp.c b/tcp.c
index a470120..2a4a799 100644 (file)
--- a/tcp.c
+++ b/tcp.c
@@ -75,6 +75,7 @@ int tcpconnect(struct server *server, struct timeval *when, int timeout, char *t
        debug(DBG_ERR, "tcpconnect: connecttcp failed");
     }
     debug(DBG_WARN, "tcpconnect: TCP connection to %s port %s up", server->conf->host, server->conf->port);
+    server->connectionok = 1;
     gettimeofday(&server->lastconnecttry, NULL);
     pthread_mutex_unlock(&server->lock);
     return 1;
@@ -150,18 +151,15 @@ unsigned char *radtcpget(int s, int timeout) {
 int clientradputtcp(struct server *server, unsigned char *rad) {
     int cnt;
     size_t len;
-    struct timeval lastconnecttry;
     struct clsrvconf *conf = server->conf;
-    
+
+    if (!server->connectionok)
+       return 0;
     len = RADLEN(rad);
-    lastconnecttry = server->lastconnecttry;
-    while ((cnt = write(server->sock, rad, len)) <= 0) {
+    if ((cnt = write(server->sock, rad, len)) <= 0) {
        debug(DBG_ERR, "clientradputtcp: write error");
-       tcpconnect(server, &lastconnecttry, 0, "clientradputtcp");
-       lastconnecttry = server->lastconnecttry;
+       return 0;
     }
-
-    server->connectionok = 1;
     debug(DBG_DBG, "clientradputtcp: Sent %d bytes, Radius packet of length %d to TCP peer %s", cnt, len, conf->host);
     return 1;
 }
@@ -190,9 +188,9 @@ void *tcpserverwr(void *arg) {
     int cnt;
     struct client *client = (struct client *)arg;
     struct queue *replyq;
-    struct reply *reply;
+    struct request *reply;
     
-    debug(DBG_DBG, "tcpserverwr: starting for %s", client->conf->host);
+    debug(DBG_DBG, "tcpserverwr: starting for %s", addr2string(client->addr));
     replyq = client->replyq;
     for (;;) {
        pthread_mutex_lock(&replyq->mutex);
@@ -209,24 +207,24 @@ void *tcpserverwr(void *arg) {
                pthread_exit(NULL);
            }
        }
-       reply = (struct reply *)list_shift(replyq->entries);
+       reply = (struct request *)list_shift(replyq->entries);
        pthread_mutex_unlock(&replyq->mutex);
-       cnt = write(client->sock, reply->buf, RADLEN(reply->buf));
+       cnt = write(client->sock, reply->replybuf, RADLEN(reply->replybuf));
        if (cnt > 0)
-           debug(DBG_DBG, "tcpserverwr: sent %d bytes, Radius packet of length %d",
-                 cnt, RADLEN(reply->buf));
+           debug(DBG_DBG, "tcpserverwr: sent %d bytes, Radius packet of length %d to %s",
+                 cnt, RADLEN(reply->replybuf), addr2string(client->addr));
        else
-           debug(DBG_ERR, "tcpserverwr: write error for %s", client->conf->host);
-       free(reply->buf);
-       free(reply);
+           debug(DBG_ERR, "tcpserverwr: write error for %s", addr2string(client->addr));
+       freerq(reply);
     }
 }
 
 void tcpserverrd(struct client *client) {
-    struct request rq;
+    struct request *rq;
+    uint8_t *buf;
     pthread_t tcpserverwrth;
     
-    debug(DBG_DBG, "tcpserverrd: starting for %s", client->conf->host);
+    debug(DBG_DBG, "tcpserverrd: starting for %s", addr2string(client->addr));
     
     if (pthread_create(&tcpserverwrth, NULL, tcpserverwr, (void *)client)) {
        debug(DBG_ERR, "tcpserverrd: pthread_create failed");
@@ -234,16 +232,21 @@ void tcpserverrd(struct client *client) {
     }
 
     for (;;) {
-       memset(&rq, 0, sizeof(struct request));
-       rq.buf = radtcpget(client->sock, 0);
-       if (!rq.buf) {
-           debug(DBG_ERR, "tcpserverrd: connection from %s lost", client->conf->host);
+       buf = radtcpget(client->sock, 0);
+       if (!buf) {
+           debug(DBG_ERR, "tcpserverrd: connection from %s lost", addr2string(client->addr));
            break;
        }
-       debug(DBG_DBG, "tcpserverrd: got Radius message from %s", client->conf->host);
-       rq.from = client;
-       if (!radsrv(&rq)) {
-           debug(DBG_ERR, "tcpserverrd: message authentication/validation failed, closing connection from %s", client->conf->host);
+       debug(DBG_DBG, "tcpserverrd: got Radius message from %s", addr2string(client->addr));
+       rq = newrequest();
+       if (!rq) {
+           free(buf);
+           continue;
+       }
+       rq->buf = buf;
+       rq->from = client;
+       if (!radsrv(rq)) {
+           debug(DBG_ERR, "tcpserverrd: message authentication/validation failed, closing connection from %s", addr2string(client->addr));
            break;
        }
     }
@@ -256,9 +259,8 @@ void tcpserverrd(struct client *client) {
     debug(DBG_DBG, "tcpserverrd: waiting for writer to end");
     pthread_join(tcpserverwrth, NULL);
     removeclientrqs(client);
-    debug(DBG_DBG, "tcpserverrd: reader for %s exiting", client->conf->host);
+    debug(DBG_DBG, "tcpserverrd: reader for %s exiting", addr2string(client->addr));
 }
-
 void *tcpservernew(void *arg) {
     int s;
     struct sockaddr_storage from;
@@ -271,13 +273,14 @@ void *tcpservernew(void *arg) {
        debug(DBG_DBG, "tcpservernew: getpeername failed, exiting");
        goto exit;
     }
-    debug(DBG_WARN, "tcpservernew: incoming TCP connection from %s", addr2string((struct sockaddr *)&from, fromlen));
+    debug(DBG_WARN, "tcpservernew: incoming TCP connection from %s", addr2string((struct sockaddr *)&from));
 
     conf = find_clconf(RAD_TCP, (struct sockaddr *)&from, NULL);
     if (conf) {
-       client = addclient(conf);
+       client = addclient(conf, 1);
        if (client) {
            client->sock = s;
+           client->addr = addr_copy((struct sockaddr *)&from);
            tcpserverrd(client);
            removeclient(client);
        } else