changelog shortlog tags branches files raw gz bz2 help

Mercurial > hg > plan9front / changeset: sshnet: pass on open failure error message, simplify

changeset 7128: d9ebec7d14e8
parent 7127: 2a70b2df336c
child 7129: 819322c2a38f
author: cinap_lenrek@felloff.net
date: Wed, 03 Apr 2019 13:45:54 +0200
files: sys/src/cmd/sshnet.c
description: sshnet: pass on open failure error message, simplify

return the error message from MSG_CHANNEL_OPEN_FAILURE
in the "connect" control write.

use a extra state "Finished" to distinguish server from client
initiated teardown. that way we do not need to track if we
send the MSG_CHANNEL_CLOSE message in closeclient(). this way
we also cannot be fooled by misbehaving server.

simplify hangupclient() by removing state transitions and doing
them in the caller explicitely. that way we can use hangupclient()
instead of dialedclient().
     1.1--- a/sys/src/cmd/sshnet.c
     1.2+++ b/sys/src/cmd/sshnet.c
     1.3@@ -46,6 +46,7 @@ enum
     1.4 	Dialing,
     1.5 	Established,
     1.6 	Teardown,
     1.7+	Finished,
     1.8 };
     1.9 
    1.10 char *statestr[] = {
    1.11@@ -53,6 +54,7 @@ char *statestr[] = {
    1.12 	"Dialing",
    1.13 	"Established",
    1.14 	"Teardown",
    1.15+	"Finished",
    1.16 };
    1.17 
    1.18 struct Client
    1.19@@ -61,7 +63,6 @@ struct Client
    1.20 	int state;
    1.21 	int num;
    1.22 	int servernum;
    1.23-	int sentclose;
    1.24 	char *connect;
    1.25 
    1.26 	int sendpkt;
    1.27@@ -120,7 +121,6 @@ char *mtpt;
    1.28 int sshfd;
    1.29 int localport;
    1.30 char localip[] = "::";
    1.31-char Ehangup[] = "hangup on network connection";
    1.32 
    1.33 int
    1.34 vpack(uchar *p, int n, char *fmt, va_list a)
    1.35@@ -434,23 +434,7 @@ findreq(Client *c, Req *r)
    1.36 }
    1.37 
    1.38 void
    1.39-dialedclient(Client *c)
    1.40-{
    1.41-	Req *r;
    1.42-
    1.43-	if(r=c->wq){
    1.44-		if(r->aux != nil)
    1.45-			sysfatal("more than one outstanding dial request (BUG)");
    1.46-		if(c->state == Established)
    1.47-			respond(r, nil);
    1.48-		else
    1.49-			respond(r, "connect failed");
    1.50-	}
    1.51-	c->wq = nil;
    1.52-}
    1.53-
    1.54-void
    1.55-hangupclient(Client *c)
    1.56+hangupclient(Client *c, char *err)
    1.57 {
    1.58 	Req *r;
    1.59 
    1.60@@ -460,22 +444,17 @@ hangupclient(Client *c)
    1.61 	while((r = c->wq) != nil){
    1.62 		c->wq = r->aux;
    1.63 		r->aux = nil;
    1.64-		respond(r, Ehangup);
    1.65+		respond(r, err);
    1.66 	}
    1.67-	if(c->state == Established){
    1.68-		c->state = Teardown;
    1.69-		matchrmsgs(c);
    1.70-		return;
    1.71-	}
    1.72-	c->state = Closed;
    1.73+	matchrmsgs(c);
    1.74 }
    1.75 
    1.76 void
    1.77 teardownclient(Client *c)
    1.78 {
    1.79-	hangupclient(c);
    1.80-	if(c->sentclose++ == 0)
    1.81-		sendmsg(pack(nil, "bu", MSG_CHANNEL_CLOSE, c->servernum));
    1.82+	c->state = Teardown;
    1.83+	hangupclient(c, "i/o on hungup channel");
    1.84+	sendmsg(pack(nil, "bu", MSG_CHANNEL_CLOSE, c->servernum));
    1.85 }
    1.86 
    1.87 void
    1.88@@ -485,14 +464,21 @@ closeclient(Client *c)
    1.89 
    1.90 	if(--c->ref)
    1.91 		return;
    1.92-	if(c->state >= Established)
    1.93+	switch(c->state){
    1.94+	case Established:
    1.95 		teardownclient(c);
    1.96+		break;
    1.97+	case Finished:
    1.98+		c->state = Closed;
    1.99+		sendmsg(pack(nil, "bu", MSG_CHANNEL_CLOSE, c->servernum));
   1.100+		break;
   1.101+	}
   1.102 	while((m = c->mq) != nil){
   1.103 		c->mq = m->link;
   1.104 		free(m);
   1.105 	}
   1.106 }
   1.107-	
   1.108+
   1.109 void
   1.110 sshreadproc(void*)
   1.111 {
   1.112@@ -813,9 +799,7 @@ ctlwrite(Req *r, Client *c)
   1.113 		nf = getfields(f[1], f, nelem(f), 0, "!");
   1.114 		if(nf != 2)
   1.115 			goto Badarg;
   1.116-		c->eof = 0;
   1.117-		c->sendwin = MaxPacket;
   1.118-		c->recvwin = WinPackets * MaxPacket;
   1.119+		c->recvwin = WinPackets*MaxPacket;
   1.120 		c->recvacc = 0;
   1.121 		c->state = Dialing;
   1.122 		queuewreq(c, r);
   1.123@@ -1074,8 +1058,17 @@ handlemsg(Msg *m)
   1.124 		if(unpack(m, "_u", &chan) < 0)
   1.125 			break;
   1.126 		c = getclient(chan);
   1.127-		if(c != nil && c->state >= Established)
   1.128-			hangupclient(c);
   1.129+		if(c == nil)
   1.130+			break;
   1.131+		switch(c->state){
   1.132+		case Established:
   1.133+			c->state = Finished;
   1.134+			hangupclient(c, "connection closed");
   1.135+			break;
   1.136+		case Teardown:
   1.137+			c->state = Closed;
   1.138+			break;
   1.139+		}
   1.140 		break;
   1.141 	case MSG_CHANNEL_OPEN_CONFIRMATION:
   1.142 		if(unpack(m, "_uuuu", &chan, &n, &win, &pkt) < 0)
   1.143@@ -1089,25 +1082,31 @@ handlemsg(Msg *m)
   1.144 			break;
   1.145 		if(pkt <= 0 || pkt > MaxPacket)
   1.146 			pkt = MaxPacket;
   1.147+		c->eof = 0;
   1.148 		c->sendpkt = pkt;
   1.149 		c->sendwin = win;
   1.150 		c->servernum = n;
   1.151-		c->sentclose = 0;
   1.152 		c->state = Established;
   1.153-		dialedclient(c);
   1.154+		if(c->wq != nil){
   1.155+			respond(c->wq, nil);
   1.156+			c->wq = nil;
   1.157+		}
   1.158 		break;
   1.159 	case MSG_CHANNEL_OPEN_FAILURE:
   1.160 		if(unpack(m, "_u____s", &chan, &s, &n) < 0)
   1.161 			break;
   1.162+		s = smprint("%.*s", utfnlen(s, n), s);
   1.163 		if(chan == SESSIONCHAN){
   1.164-			sendp(ssherrchan, smprint("%.*s", utfnlen(s, n), s));
   1.165+			sendp(ssherrchan, s);
   1.166 			break;
   1.167 		}
   1.168 		c = getclient(chan);
   1.169-		if(c == nil || c->state != Dialing)
   1.170+		if(c == nil || c->state != Dialing){
   1.171+			free(s);
   1.172 			break;
   1.173+		}
   1.174 		c->state = Closed;
   1.175-		dialedclient(c);
   1.176+		hangupclient(c, s);
   1.177 		break;
   1.178 	}
   1.179 	free(m);