source: trunk/third/openssh/compress.c @ 18759

Revision 18759, 4.9 KB checked in by zacheiss, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18758, which included commits to RCS files with non-trunk default branches.
Line 
1/*
2 * Author: Tatu Ylonen <ylo@cs.hut.fi>
3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4 *                    All rights reserved
5 * Interface to packet compression for ssh.
6 *
7 * As far as I am concerned, the code I have written for this software
8 * can be used freely for any purpose.  Any derived versions of this
9 * software must be clearly marked as such, and if the derived work is
10 * incompatible with the protocol description in the RFC file, it must be
11 * called by a name other than "ssh" or "Secure Shell".
12 */
13
14#include "includes.h"
15RCSID("$OpenBSD: compress.c,v 1.19 2002/03/18 17:31:54 provos Exp $");
16
17#include "log.h"
18#include "buffer.h"
19#include "zlib.h"
20#include "compress.h"
21
22z_stream incoming_stream;
23z_stream outgoing_stream;
24static int compress_init_send_called = 0;
25static int compress_init_recv_called = 0;
26static int inflate_failed = 0;
27static int deflate_failed = 0;
28
29/*
30 * Initializes compression; level is compression level from 1 to 9
31 * (as in gzip).
32 */
33
34void
35buffer_compress_init_send(int level)
36{
37        if (compress_init_send_called == 1)
38                deflateEnd(&outgoing_stream);
39        compress_init_send_called = 1;
40        debug("Enabling compression at level %d.", level);
41        if (level < 1 || level > 9)
42                fatal("Bad compression level %d.", level);
43        deflateInit(&outgoing_stream, level);
44}
45void
46buffer_compress_init_recv(void)
47{
48        if (compress_init_recv_called == 1)
49                inflateEnd(&incoming_stream);
50        compress_init_recv_called = 1;
51        inflateInit(&incoming_stream);
52}
53
54/* Frees any data structures allocated for compression. */
55
56void
57buffer_compress_uninit(void)
58{
59        debug("compress outgoing: raw data %lu, compressed %lu, factor %.2f",
60            outgoing_stream.total_in, outgoing_stream.total_out,
61            outgoing_stream.total_in == 0 ? 0.0 :
62            (double) outgoing_stream.total_out / outgoing_stream.total_in);
63        debug("compress incoming: raw data %lu, compressed %lu, factor %.2f",
64            incoming_stream.total_out, incoming_stream.total_in,
65            incoming_stream.total_out == 0 ? 0.0 :
66            (double) incoming_stream.total_in / incoming_stream.total_out);
67        if (compress_init_recv_called == 1 && inflate_failed == 0)
68                inflateEnd(&incoming_stream);
69        if (compress_init_send_called == 1 && deflate_failed == 0)
70                deflateEnd(&outgoing_stream);
71}
72
73/*
74 * Compresses the contents of input_buffer into output_buffer.  All packets
75 * compressed using this function will form a single compressed data stream;
76 * however, data will be flushed at the end of every call so that each
77 * output_buffer can be decompressed independently (but in the appropriate
78 * order since they together form a single compression stream) by the
79 * receiver.  This appends the compressed data to the output buffer.
80 */
81
82void
83buffer_compress(Buffer * input_buffer, Buffer * output_buffer)
84{
85        u_char buf[4096];
86        int status;
87
88        /* This case is not handled below. */
89        if (buffer_len(input_buffer) == 0)
90                return;
91
92        /* Input is the contents of the input buffer. */
93        outgoing_stream.next_in = buffer_ptr(input_buffer);
94        outgoing_stream.avail_in = buffer_len(input_buffer);
95
96        /* Loop compressing until deflate() returns with avail_out != 0. */
97        do {
98                /* Set up fixed-size output buffer. */
99                outgoing_stream.next_out = buf;
100                outgoing_stream.avail_out = sizeof(buf);
101
102                /* Compress as much data into the buffer as possible. */
103                status = deflate(&outgoing_stream, Z_PARTIAL_FLUSH);
104                switch (status) {
105                case Z_OK:
106                        /* Append compressed data to output_buffer. */
107                        buffer_append(output_buffer, buf,
108                            sizeof(buf) - outgoing_stream.avail_out);
109                        break;
110                default:
111                        deflate_failed = 1;
112                        fatal("buffer_compress: deflate returned %d", status);
113                        /* NOTREACHED */
114                }
115        } while (outgoing_stream.avail_out == 0);
116}
117
118/*
119 * Uncompresses the contents of input_buffer into output_buffer.  All packets
120 * uncompressed using this function will form a single compressed data
121 * stream; however, data will be flushed at the end of every call so that
122 * each output_buffer.  This must be called for the same size units that the
123 * buffer_compress was called, and in the same order that buffers compressed
124 * with that.  This appends the uncompressed data to the output buffer.
125 */
126
127void
128buffer_uncompress(Buffer * input_buffer, Buffer * output_buffer)
129{
130        u_char buf[4096];
131        int status;
132
133        incoming_stream.next_in = buffer_ptr(input_buffer);
134        incoming_stream.avail_in = buffer_len(input_buffer);
135
136        for (;;) {
137                /* Set up fixed-size output buffer. */
138                incoming_stream.next_out = buf;
139                incoming_stream.avail_out = sizeof(buf);
140
141                status = inflate(&incoming_stream, Z_PARTIAL_FLUSH);
142                switch (status) {
143                case Z_OK:
144                        buffer_append(output_buffer, buf,
145                            sizeof(buf) - incoming_stream.avail_out);
146                        break;
147                case Z_BUF_ERROR:
148                        /*
149                         * Comments in zlib.h say that we should keep calling
150                         * inflate() until we get an error.  This appears to
151                         * be the error that we get.
152                         */
153                        return;
154                default:
155                        inflate_failed = 1;
156                        fatal("buffer_uncompress: inflate returned %d", status);
157                        /* NOTREACHED */
158                }
159        }
160}
Note: See TracBrowser for help on using the repository browser.