(cp)[0] = (value) >> 8, \
(cp)[1] = (value) )
-extern void sshfwd_close(void *);
-extern void sshfwd_write(void *, char *, int);
-
struct pfwd_queue {
struct pfwd_queue *next;
char *buf;
void *c; /* (channel) data used by ssh.c */
Socket s;
char hostname[128];
+ int throttled, throttle_override;
int port;
int ready;
struct pfwd_queue *waiting;
static int pfd_receive(Plug plug, int urgent, char *data, int len)
{
struct PFwdPrivate *pr = (struct PFwdPrivate *) plug;
-
- if (pr->ready)
- sshfwd_write(pr->c, data, len);
+ if (pr->ready) {
+ if (sshfwd_write(pr->c, data, len) > 0) {
+ pr->throttled = 1;
+ sk_set_frozen(pr->s, 1);
+ }
+ }
return 1;
}
+static void pfd_sent(Plug plug, int bufsize)
+{
+ struct PFwdPrivate *pr = (struct PFwdPrivate *) plug;
+
+ sshfwd_unthrottle(pr->c, bufsize);
+}
+
/*
* Called when receiving a PORT OPEN from the server
*/
static struct plug_function_table fn_table = {
pfd_closing,
pfd_receive,
+ pfd_sent,
NULL
};
*/
pr = (struct PFwdPrivate *) smalloc(sizeof(struct PFwdPrivate));
pr->fn = &fn_table;
+ pr->throttled = pr->throttle_override = 0;
pr->ready = 1;
pr->c = c;
- pr->s = *s = sk_new(addr, port, 0, 1, (Plug) pr);
+ pr->s = *s = new_connection(addr, dummy_realhost, port, 0, 1, 0, (Plug) pr);
if ((err = sk_socket_error(*s))) {
sfree(pr);
return err;
called when someone connects to the local port
*/
-static int pfd_accepting(Plug p, struct sockaddr *addr, void *sock)
+static int pfd_accepting(Plug p, void *sock)
{
- /* for now always accept this socket */
static struct plug_function_table fn_table = {
pfd_closing,
pfd_receive,
+ pfd_sent,
NULL
};
struct PFwdPrivate *pr, *org;
- struct sockaddr_in *sin = (struct sockaddr_in *)addr;
Socket s;
char *err;
- if (ntohl(sin->sin_addr.s_addr) != 0x7F000001 && !cfg.lport_acceptall)
- return 1; /* denied */
-
org = (struct PFwdPrivate *)p;
pr = (struct PFwdPrivate *) smalloc(sizeof(struct PFwdPrivate));
pr->fn = &fn_table;
strcpy(pr->hostname, org->hostname);
pr->port = org->port;
+ pr->throttled = pr->throttle_override = 0;
pr->ready = 0;
pr->waiting = NULL;
/* Add a new forwarding from port -> desthost:destport
- sets up a listenner on the local machine on port
+ sets up a listener on the local machine on port
*/
char *pfd_addforward(char *desthost, int destport, int port)
{
static struct plug_function_table fn_table = {
pfd_closing,
- pfd_receive, /* should not happen... */
+ pfd_receive, /* should not happen... */
+ pfd_sent, /* also should not happen */
pfd_accepting
};
pr->c = NULL;
strcpy(pr->hostname, desthost);
pr->port = destport;
+ pr->throttled = pr->throttle_override = 0;
pr->ready = 0;
pr->waiting = NULL;
- pr->s = s = sk_newlistenner(port, (Plug) pr);
+ pr->s = s = new_listener(port, (Plug) pr, !cfg.lport_acceptall);
if ((err = sk_socket_error(s))) {
sfree(pr);
return err;
sk_close(s);
}
+void pfd_unthrottle(Socket s)
+{
+ struct PFwdPrivate *pr;
+ if (!s)
+ return;
+ pr = (struct PFwdPrivate *) sk_get_private_ptr(s);
+
+ pr->throttled = 0;
+ sk_set_frozen(s, pr->throttled || pr->throttle_override);
+}
+
+void pfd_override_throttle(Socket s, int enable)
+{
+ struct PFwdPrivate *pr;
+ if (!s)
+ return;
+ pr = (struct PFwdPrivate *) sk_get_private_ptr(s);
+
+ pr->throttle_override = enable;
+ sk_set_frozen(s, pr->throttled || pr->throttle_override);
+}
+
/*
* Called to send data down the raw connection.
*/
-void pfd_send(Socket s, char *data, int len)
+int pfd_send(Socket s, char *data, int len)
{
- struct PFwdPrivate *pr = (struct PFwdPrivate *) sk_get_private_ptr(s);
-
if (s == NULL)
- return;
-
- sk_write(s, data, len);
+ return 0;
+ return sk_write(s, data, len);
}
void pfd_confirm(Socket s)
{
- struct PFwdPrivate *pr = (struct PFwdPrivate *) sk_get_private_ptr(s);
+ struct PFwdPrivate *pr;
if (s == NULL)
return;
+ pr = (struct PFwdPrivate *) sk_get_private_ptr(s);
pr->ready = 1;
sk_set_frozen(s, 0);
sk_write(s, NULL, 0);