LINUX.ORG.RU

[kernel] Zlib

 


0

1

Хочу узнать, как в ядре правильно использовать Gzip сжатие?

К примеру, у меня есть указатель на сжатые данные (сжатие gzip), как мне получить оригинальный вид данных? И как произвести обратное действие?

Если можно, буду рад примеру кода)

Deleted

Последнее исправление: Deleted (всего исправлений: 1)

Нужно смотреть в районе crypto/zlib.c. Точнее не скажу, со сжатием дела не имел.

ttnl ★★★★★
()

Хотя скажу. Куча примеров сжатия есть в crypto/testmgr.c. Если выдирать оттуда, то пример такой:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/crypto.h>
#include <linux/err.h>
#include <crypto/compress.h>
#include <linux/netlink.h>

#define COMP_BUF_SIZE	512

struct pcomp_testvec {
	void *params;
	unsigned int paramsize;
	int inlen, outlen;
	char input[COMP_BUF_SIZE];
};

static const struct a {
	struct nlattr nla;
	int val;
} deflate_decomp_params = {
	.nla = {
		.nla_len        = NLA_HDRLEN + sizeof(int),
		.nla_type       = ZLIB_DECOMP_WINDOWBITS,
	},
	.val                    = -11,
};

static struct pcomp_testvec vec = {
	.params = (void *)&deflate_decomp_params,
	.paramsize = sizeof(deflate_decomp_params),
	.inlen  = 122,
	.outlen = 191,
	.input  = "\x5d\x8d\x31\x0e\xc2\x30\x10\x04"
		  "\xbf\xb2\x2f\xc8\x1f\x10\x04\x09"
		  "\x89\xc2\x85\x3f\x70\xb1\x2f\xf8"
		  "\x24\xdb\x67\xd9\x47\xc1\xef\x49"
		  "\x68\x12\x51\xae\x76\x67\xd6\x27"
		  "\x19\x88\x1a\xde\x85\xab\x21\xf2"
		  "\x08\x5d\x16\x1e\x20\x04\x2d\xad"
		  "\xf3\x18\xa2\x15\x85\x2d\x69\xc4"
		  "\x42\x83\x23\xb6\x6c\x89\x71\x9b"
		  "\xef\xcf\x8b\x9f\xcf\x33\xca\x2f"
		  "\xed\x62\xa9\x4c\x80\xff\x13\xaf"
		  "\x52\x37\xed\x0e\x52\x6b\x59\x02"
		  "\xd9\x4e\xe8\x7a\x76\x1d\x02\x98"
		  "\xfe\x8a\x87\x83\xa3\x4f\x56\x8a"
		  "\xb8\x9e\x8e\x5c\x57\xd3\xa0\x79"
		  "\xfa\x02",
};

static int test_init(void)
{
	struct crypto_pcomp *tfm;
	struct comp_request req;
	char result[COMP_BUF_SIZE];
	int res;
	const char *algo = "zlib";
	unsigned int produced = 0;

	tfm = crypto_alloc_pcomp("zlib", 0, CRYPTO_ALG_TYPE_PCOMPRESS);
	if (IS_ERR(tfm)) {
		printk("Unable to allocate crypto_comp for zlib\n");
		return PTR_ERR(tfm);
	}

	memset(result, 0, sizeof(result));

	res = crypto_decompress_setup(tfm, vec.params, vec.paramsize);
	if (res) {
		pr_err("alg: pcomp: decompression setup failed on "
		       "test %s: error=%d\n", algo, res);
		return res;
	}

	res = crypto_decompress_init(tfm);

	if (res) {
		pr_err("alg: pcomp: decompression init failed on test "
		       "%s: error=%d\n", algo, res);
		return res;
	}

	req.next_in = vec.input;
	req.avail_in = vec.inlen / 2;
	req.next_out = result;
	req.avail_out = vec.outlen / 2;	

	res = crypto_decompress_update(tfm, &req);
	if (res < 0 && (res != -EAGAIN || req.avail_in)) {
		pr_err("alg: pcomp: decompression update failed on "
		       "test %s: error=%d\n", algo, res);
		return res;
	}
	if (res > 0)
		produced += res;

	/* Add remaining input data */
	req.avail_in += (vec.inlen + 1) / 2;
	
	res = crypto_decompress_update(tfm, &req);
	if (res < 0 && (res != -EAGAIN || req.avail_in)) {
		pr_err("alg: pcomp: decompression update failed on "
		       "test %s: error=%d\n", algo, res);
		return res;
	}
	if (res > 0)
		produced += res;
	
	/* Provide remaining output space */
	req.avail_out += COMP_BUF_SIZE - vec.outlen / 2;
	
	res = crypto_decompress_final(tfm, &req);
	if (res < 0 && (res != -EAGAIN || req.avail_in)) {
		pr_err("alg: pcomp: decompression final failed on "
		       "test %s: error=%d\n", algo, res);
		return res;
	}
	if (res > 0)
		produced += res;
	
	if (COMP_BUF_SIZE - req.avail_out != vec.outlen) {
		pr_err("alg: comp: Decompression test failed for "
		       "%s: output len = %d (expected %d)\n",
		       algo, COMP_BUF_SIZE - req.avail_out,
		       vec.outlen);
		return -EINVAL;
	}
	
	if (produced != vec.outlen) {
		pr_err("alg: comp: Decompression test failed for "
		       "%s: returned len = %u (expected %d)\n",
		       algo, produced, vec.outlen);
		return -EINVAL;
	}

	printk(KERN_INFO "Decompression was successful:\n===\n");
	printk(KERN_INFO "%s\n", result);
	printk(KERN_INFO "===\n");
	
	crypto_free_pcomp(tfm);
	return 0;
}
static void test_exit(void)
{
}

module_init(test_init);
module_exit(test_exit);
MODULE_LICENSE("GPL");

Если будешь экспериментировать, убери printk, из-за него может падать, если неправильно расшифруется.

ttnl ★★★★★
()
Ответ на: комментарий от ttnl

ttnl ОГРОМНОЕ СПАСИБО! за пример кода) это оказывается то что мне нужно.
Однако при его тесте, возникли следующие вопросы.
При разархивировании тестовых данных(vec.input), разжатие проходит как по маслу. и выводится разжатая строка.
Но при попытке декомпрессии моих данных, мне сигнализируют об ошибке -22 после выполнении функции res = crypto_decompress_update(tfm, &req);
Перед этим, я сжатые данные методом gzip записываю в vec.input .
Также в vec проставляю длину данных равную PAGE .
Почему мои данные не разжимаются? и почему вылазит эта ошибка? Или можно сформулировать вопрос проще, как сделать так, чтоб на этом примере разжимались мои данные??? (звучит глупо.. но всёже)

Deleted
()
Ответ на: комментарий от Deleted

-22 — это EINVAL, значит подаешь какие-то неправильные входные данные. Может быть размер буферов, а может и что-то другое.

Навставляй отладочных печатей, начиная с функции zlib_decompress_update(), тогда будет понятно, в чем проблема. Более конкретно тут сложно сказать.

ttnl ★★★★★
()
Ответ на: комментарий от ttnl

Вы были правы, не верные данные для декомпрессии я подавал.

И у меня новый вопрос, даже два вопроса.
Первый в том, что декомпрессия нормально работает только для не больших данных (каких именно, я не определил... кажется больше размера PAGE). Как быть с декомпрессией данных произвольной длины??

Как производить сжатие данных?

Deleted
()
Ответ на: комментарий от Deleted

Дополню. При декопрессии больших данных, выдаётся ошибка -11

Deleted
()
Ответ на: комментарий от Deleted

>При декопрессии больших данных, выдаётся ошибка -11

-11 — это EAGAIN. Черт его знает. Возможно у буфер маловат. Все ещё не хочешь посмотреть ф-цию zlib_decompress_update()?

Как производить сжатие данных?

См. crypto/testmgr.c. Там примеры на все виды криптографии.

ttnl ★★★★★
()
Ответ на: комментарий от ttnl

Начинаю разбор функций. Смотрю zlib_decompress_update
За день постараюсь разобраться.

Deleted
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.