현재 로그인한 계정의 홈폴더 (~)에 ".vimrc" 파일 생성 후 아래 내용 저장

set fileencodings=utf-8,euc-kr
set encoding=utf-8

'develop > linux' 카테고리의 다른 글

vi euc-kr, utf-8  (0) 2019.12.24
TTFB 체크 명령어  (0) 2016.02.16
GNU C, __attribute__  (0) 2014.10.14
Linux C에서 키보드 이벤트 받기(kbhit())  (0) 2014.02.28
NAT 종류별 설정  (0) 2014.02.17

출처:http://egloos.zum.com/indirock/v/3791689

[vi 에디터 utf8 <-> euc-kr 웹문서 encoding 전환하기]
원문: (http://onlyu.blog.me/60123862837)

 

vi로 웹문서를 열어 보면 한글이 깨어져 있고

<meta http-equiv=Content-Type Content="text/html; charset=euc-kr">이 보인다면

리눅스 콘솔창에 env 해 볼때 LANG=ko_KR.UTF-8 으로 나온면 utf8 환경입니다.

 

Q) 그럼 한글이 깨어져 보이는 utf-8 시스템 환경에서 euc-kr 웹문서를 제대로 볼 수 없는 것인가?

A) 리눅스 환경이라면 vi 환경설정 파일인 .vimrc 파일 set fileencodings=utf8,euc-kr 를 추가하면 문서를 열때 자동적으로 fileencoding이 utf8인지 euc-kr 인지 encoding에 맞게 열고 저장을 합니다.

계정 로그아웃(재접속)하지 않고 vi 설정을 적용할려면 콘솔에서 source .vimrc 하고 엔터키를 누르면 됩니다.

 

Q) 그럼 euc-kr 파일 웹문서를 utf8 파일로 변경을 하고 싶다면 어떻게 하죠?

A) vi로 파일을 열고 나서

:set fileencoding=utf-8

:w

 

하면 됩니다. 저장 후 종료를 할려면 :wq 엔터를 하면 됩니다.

반대로 utf8 문서를 euc-kr로 변경 할려면 :set fileencoding=euc-kr을 하면 됩니다.

 

 

euc-kr 웹문서를 utf8로 변경 하고 저장 했다면

<meta http-equiv=Content-Type Content="text/html; charset=utf-8">

로 하지 않으면 웹브라우저에서 확인시에는 다시 한글이 깨어져 보이겠죠.

 

 

 

 

 

Q) vi 에디터로 열지 않고 euc-kr 웹문서를 utf8로 변경 할려고 합니다. 어떻게 해야 하죠?

 

A) iconv 명령어로 가능합니다.

 

iconv -f euc-kr -t utf-8 euc-kr.html --output utf8.html

 

or 

 

iconv -f euc-kr -t utf-8 euc-kr.html > utf8.html

 

 

 

Q)한개 파일이 아니라 여러개의 html 파일을 동시에 변경 할려면 어떻게 하죠?

 

백업 파일처럼 utf8.html로 할 필요없이 그냥 utf-8 파일로 변환 되면 좋겠는데요??

 

A)

 

변경을 원하는 경로로 이동을 하고 아래와 같은 명령어로 한방에 그럼 변경해 보겠습니다.

 

cd /web/files 

 

for I in ./-.html ; do iconv -c -f euc-kr -t utf-8 $I > $I.tmp && mv $I.tmp $I ; done

 

 

 

작업 완료 전에는 무조건 백업본을 유지하는 것이 좋습니다. 그냥 원본폴더를 tar로 묶어 두면 되죠. 

 

시스템 환경에 따라 작업 환경에 따라 charset encoding은 테스트 작업을 하고 본격적으로 진입 하는 것이 바람직합니다.  

 

 

 

Q) recode 명령어로 한번에 변경 할 수 있다고 하는데 어떻게 하나요?

 

A) 먼저 시스템에 recode 명령어를 사용할 수 있는지 확인 해야 하는데

 

rpm -qi recode 해서 아무것도 안나오면 설치 해야합니다.

 

yum install recode recode-devel 또는 rpm을 찾아서 설치 하거나 

 

http://recode.progiciels-bpi.ca/index.html 접속해서 파일을 받아서 설치합니다.

 

recode 명령어로 얼마나 많은 charset 변경을 할 수 있는지 확인은

 

recode -l 로 살펴 보면 됩니다. 그럼 euc-kr에서 utf-8로 변경 명령어는 아래와 같습니다.

 

 

 

recode -v <소스 CHARSET>...<변환 CHARSET> <파일명>

 

recode -v EUC-KR...UTF-8 *.html

 

 

 

 

 

Q) php에서 특정 문자열만 euc-kr 또는 utf8로 할려면 어떻게 하죠?

 

A) iconv 함수를 이용하면 됩니다.

 

iconv("euc-kr", "utf-8", $str); // euc-kr을 utf8로 encoding 됩니다.

 

iconv("utf-8", "euc-kr", $str); // utf8을 euc-kr로 encoding 됩니다.

 

참조 URL : http://www.php.net/manual/en/function.iconv.php

 

 

 

 

 

Q) java,jsp에서 문자열 encoding 전환은?

 

A)

 

StringBuffer szBuffer = new StringBuffer();
String str = new String(szBuffer.toString().getBytes("UTF-8"), "EUC-KR");

 

http://download.oracle.com/javase/1.5.0/docs/guide/intl/encoding.doc.html

 

여전히 한글이 깨어진다면 아래 상황을 체크 해 봅니다.

 

1. <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

 

2. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

 

3. <Connector URIEncoding="UTF-8" connectionTimeout="10000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
4. URIEncoding 세팅을 해 놓아도 get/post 메소드로 넘어갈때 Parameter값 한글이 깨어질때는

 

SetCharacterEncodingFilter.java 파일을 $CATALINA_HOME/common/classes (톱캣) 또는 WEB-INF/classes (개인환경) 밑에

 

javac SetCharacterEncodingFilter.java -d .

 

컴파일을 하고 web.xml 파일 encoding 필터 세팅이 되어 있는지 확인 해 봅니다.

 

* utf8 톰캣이 아니라면 톰캣 4.x 은 기본적으로 8859_1로구동이 됩니다. export LANG=en_US.iso8859-1

 

export LANG=ko_KR.eucKR 으로 한다면 charset은 euc-kr로 구동이 됩니다.

 

추가 옵션으로 export CATALINA_OPTS='-Dencoding.default=euc-kr -Dfile.encoding=euc-kr'

 

 

 

 

 

Q) 윈도우 노트패드(notepad)에서 encoding 변환 작업은 할 수 없나요?

 

A) 윈도우에서 작업 가능한 무료 에디터 notepad++를 소개 해 드립니다.

 

http://notepad-plus-plus.org/ 접속 후 다운로드(DOWNLOAD) 메뉴에서 받으시면 됩니다.

 

윈도우에서 생성한 ANSI Encoding 파일을 상단 메뉴 Encoding 에서

 

Convert to UTF-8 without BOM (UTF-8 형식으로 변환 BOM 없음) 으로 선택하시면 UTF-8 Charset 으로 변환이 됩니다.

 

 




 

(notepad++ 메뉴를 한글로 변경 Settings > Preferences > General Localization 셀렉터 항목에 한국어를 선택하면 됩니다.)

 

 

 


(추가)

 

Q) 여러 사이트에서 넘어 오는 값이 각각 다른데 utf8 인지 euc-kr 인지 어떻게 알죠?

 

A) php 경우라면 mb_detect_encoding($str); 로 찍어 보면 압니다.

 

하여 각각 원하는 encoding을 iconv로 변환을 해 주면 됩니다.

'develop > linux' 카테고리의 다른 글

vi 자동으로 encoding 설정  (0) 2024.03.07
TTFB 체크 명령어  (0) 2016.02.16
GNU C, __attribute__  (0) 2014.10.14
Linux C에서 키보드 이벤트 받기(kbhit())  (0) 2014.02.28
NAT 종류별 설정  (0) 2014.02.17

curl -o /dev/null -w "Connect: %{time_connect} TTFB: %{time_starttransfer} Total time: %{time_total} \n" [체크할 URL]

'develop > linux' 카테고리의 다른 글

vi 자동으로 encoding 설정  (0) 2024.03.07
vi euc-kr, utf-8  (0) 2019.12.24
GNU C, __attribute__  (0) 2014.10.14
Linux C에서 키보드 이벤트 받기(kbhit())  (0) 2014.02.28
NAT 종류별 설정  (0) 2014.02.17

출처: http://blog.daum.net/english_100/5


GNU C의 커다란 특성(초보자가 알기 쉽지 않지만) 중 하나는 속성(__attribute__)체계이다. __attribute__는 함수속성(Function attribute) 변수속성(Variable attribute) 그리고 타입속성(Type attribute)로 구분 된다. __attribute__의 표현 방식은 attribute의 앞과 뒤에 각각 두개씩의 아래바(__)를 붙이고 바로 이어 괄호안에 속성 인자를 쓰도록 되어있다.

 

 

1. 함수속성 (Function Atrribute) 

참조 : http://gcc.gnu.org/onlinedocs/gcc-4.6.1/gcc/Function-Attributes.html#Function-Attributes

 

GNU C에서 프로그램에서 불리워질 함수들에 대해 컴파일러로 하여금 더욱 주의하여 최적화하고 검사하도록 선언할 수 있다. __attribute__는 우리가 함수를 선언할 때 특별한 속성을 부여할 수 있다. 이 __atribute__ 다음에는 쌍괄호로 싸여진 속성인자가 따라온다.

우리는 다음의 속성 키워드의 앞뒤에 __을 붙여 사용할 수 있다. 이는 같은 이름으로 정의된 매크로들에 상관없이 헤더파일에서 이 키워드들을 사용할 수 있게 해준다.


alias ("target")

alias 속성은 함수의 선언이 이미 명기된 다른 심볼에 대한 알리아스를 발생하도록 한다. 예를 들어,

void __f() { /* Do something. */ ; }

void f() __attribute__((weak, alias("__f")));

'f'를 '__f'에 대한 약한 알리아스로 정의한다.

 

aligned(alignment)

이 속성은 함수에 대한 최소정렬을 바이트 단위로 명기한다.

함수의 정렬을 감소시키기 위해 이 속성을 사용할 수 없고 단지 증가를 위해서만 사용가능하다. 하지만 함수에 대한 정렬을 명기했을 경우 -falign-functions 옵션의 효력은 사라지게 된다.

aligned 속성에 의한 효과는 링커(linker)에 의해 제한될 수 있다. 많은 시스템에서 함수는 링커가 제공하는 최대 정렬값까지 정렬될 수 있다. (어떤 링커는 최대 정렬값이 매우 매우 매우 작다.) aligned 속성은 변수에도 사용될 수 있다. (Variable Attribute 참조)

 

alloc_size

always_inline

gnu_inline

artifical

bank_switch

flatten

error("message")

warning("message")

 

cdecl

인텔 386 시스템에서 cdecl 속성은 컴파일러로 하여금 함수 인자를 전달하기 위해 사용했던 스택공간을 호출함수가 정리(pop off)할 것으로 가정하게 한다. 이는 -mrtd 스위치 효과를 덮어씌우기 위해 사용될 수 있다.

 

const

constructor

destructor

constructor(priority)

destructor(priority)

deprecated

deprecated(msg)

disinterrupt

dllexport

dllimport

eightbit_data

exception_handler

externelly_visible

far

fast_interrupt

 

fastcall

인텔 396 시스템에서 fastcall 속성은 컴파일러로 하여금 함수의 첫째 인자는 ECX를 통해 두 번째 인자는 EDX를 통해 전달하게 한다. 이어지는 더 많은 인자들은 스택을 통해 전달한다. 스택의 인자값들은 호출된 함수에서 정리(pop off) 한다. 만약 함수에 전달되는 인자수가 가변적이라면 모든 인자들은 스택을 통해 전달된다.

 

thiscall

인텔 386 시스템에서 thiscall 속성은 컴파일러로 하여금 함수의 첫째 인자는 ECX를 통해 전달하게 한다. 이어지는 다른 인자들은 스택을 통해 전달한다. 스택값은 호출된 함수에서 정리(pop off)된다. 전달되는 함수 인자 수가 가변적이면 모든 인자들은 스택을 통해 전달된다. thiscall 속성은 C++ non-static member 함수를 위한 것이다.

 

format( archetype, string-index, first-to-check )

format 속성은 함수가 printf, scant, strftime, strfmon 등과 같은 함수 인자 스타일을 갖음을 명기함으로써 포맷 문자열에 대해 typecheck가 이루어지게 한다. 예를 들어

extern int

my_printf(void *my_object, const char *my_format, ... )

__attribute__((format (printf, 2, 3)));

        

위 선언은 컴파일러로 하여금 my_printf를 호출하기 위해 함수인자인 my_format이 printf 형식의 포맷 문자열로서 모순이 없는지를 체크하게 한다.  

파라메터 archetype은 포맷 문자열을 해석할 방식을 결정하는데 printf, scant, strftime, gnu_printf, gnu_scanf, gnu_strftime, strfmon 중에 하나이어야 한다. 파라메터 string-index는 어떤 함수인자가 포맷 문자열인지를 가리키며 first-to-check는 문자열에 대해 체크해 나갈 첫 함수인자의 번호이다. 한가지 용례로 아래의 test.c 프로그램을 보자.

1:

2: extern void myprint(const char *format, ...) __attribute__((format(print, 1, 2)));

3:

4: void test()

5:{

6:      myprint("%d\n", 4);

7:      myprint("%s\n", 4);

8:      myprint("%s\n", "abc");

9:      myprint("%s %d %d\n", 4, 6);

10:}

$gcc -Wall -c test.c test를 수행하면 다음과 같은 경고가 나타난다.

test.c: In function 'test'

test.c:7: warning: format '%d' expects type 'int', but argument 2 has type 'char *'

test.c:9: warning: format '%s' expects type 'char *', but argument 2 has type 'int'

test.c:9: warning: toot few arguments for format

만약 함수 선언중 _attribute__(()) 부분을 없애버리면 위의 경고문구는 사라지게 된다.


 

format_arg(string-index)

function_vector

interrupt

ifunc

interrupt_handler

interrupt_thread

isr

kspisusp

l1_text

l2

leaf

long_call/short_call

longcall/shortcall

long_call/near/far

malloc

mips16/nomips16

model(model-name)

ms_abi/sysv_abi

callee_pop_aggregate_return(number)

ms_hook_prologue

naked

near

nesting

nmi_handler

no_instrument_function

no_split_stack

noinline

noclone

nonull(arg-index, ...)

 

noreturn

abort 나 exit 같은 몇몇 표준 라이브러리 함수들은 반환할 수 없다. GCC는 자동으로 이를 안다. 어떤 프로그램들은 함수가 반환하지 않음을 자체적으로 정의할 수 있다. 우리는 noreturn을 선언함으로써 이를 컴파일러에게 일러줄 수 있다.

void fatal() __attribute__((noreturn));

void fatal( /* ... */ )

{

/* ... */ /* Print error message. */ /* ... */

exit(1);

}

noreturn 키워드는 컴파일러에게 fatal 함수가 반환할 수 없음을 일러준다. 그러면 이 fatal 함수가 무엇을 반환하려 하든 관계없이 최적화할 수 있다. 이는 조금 나은 코드를 만들게 하며 더 중요한 것은 초기화되지 않은 변수들에 대해 애매한 경고를 하지 않게 한다.

noreturn 함수가 void 이외의 타입을 갖는 것은 더 이상 의미가 없게 된다.

 

nothrow

optimize

pcs

pure

hot

cold

 

regparm(number)

인텔 386 시스템에서 regparm 속성은 컴파일러로 하여금 첫 번째 함수 인자로부터 number 번째 인자를 스택이 아닌 EAX, EDX ECX 등의 레지스터를 통해 전달하게 한다.

 

sseregparm

force_align_arg_pointer

resbank

return_twice

saveall

save_volatiles

section("section-name")

컴파일러가 생성한 코드는 text 영역에 두는 것이 정상적이다. 그러나 종종 추가적인 영역이 필요하거나 특별한 영역에 두어야 할 특별한 함수를 갖게 되는 경우가 있다. section 속성은 임의의 함수가 특정 영역에 있어야 함을 명기한다. 예를 들어

extern void foobar(void) __attribute__((section("bar")));

와 같이 선언하면 이는 함수 foobar를 bar 영역에 두라는 이야기이다.

어떤 파일형식은 임의의 영역을 지원하지 않으므로 section 속성은 모든 플랫폼에서 이용가능한 것은 아니다. 만약 한 모듈의 모든 내용을 하나의 영역에 두고자 한다면 링커를 이용할 수도 있다.

 

sentinel

short_call

shortcall

signal

sp_switch

 

stdcall

인텔 386 시스템에서 stdcall 속성은 컴파일러로 하여금 함수인자가 가변 개수가 아닌 이상은 인자를 전달하기 위해 사용한 스택영역을 호출된 함수에서 정리(pop off) 하는 것으로 가정하게 한다.

 

syscall_linkage

target

tiny_data

trap_exit

unused

used

version_id

visibility

vliw

warn_unused_result

weak

weakref

weakref("target")


 

 

    

2. 변수속성 (Variable Attribute)

참조 : http://gcc.gnu.org/onlinedocs/gcc-4.6.1/gcc/Variable-Attributes.html#Variable-Attributes

 

 

3. 타입속성 (Type Attribute)

참조 : http://gcc.gnu.org/onlinedocs/gcc-4.6.1/gcc/Type-Attributes.html#Type-Attributes

 


'develop > linux' 카테고리의 다른 글

vi euc-kr, utf-8  (0) 2019.12.24
TTFB 체크 명령어  (0) 2016.02.16
Linux C에서 키보드 이벤트 받기(kbhit())  (0) 2014.02.28
NAT 종류별 설정  (0) 2014.02.17
Linux TCP/IP tunning  (0) 2014.01.08

출처: http://stackoverflow.com/questions/448944/c-non-blocking-keyboard-input


windows에서 conio.h를 포함하고 _kbhit()함수를 사용하여 키보드 이벤트가 발생했는지 여부를 알 수 있는데 리눅스에서는 해당하는 함수가 없어서 검색해봄.


#ifndef WIN32

int _kbhit()

{

struct timeval tv = { 0L, 0L };

fd_set fds;

FD_ZERO(&fds);

FD_SET(0, &fds);

return select(1, &fds, NULL, NULL, &tv);

}

#endif



위의 소스로 안되는 경우가 있어서 좀 더 찾아보니 다음과 같은 것들도 있다.

출처는 linux kbhit 오픈 소스라는데... 까먹음 ;;


static struct termios initial_settings, new_settings;

static int peek_character = -1;


void init_keyboard()

{

tcgetattr(0,&initial_settings);

new_settings = initial_settings;

new_settings.c_lflag &= ~ICANON;

new_settings.c_lflag &= ~ECHO;

new_settings.c_cc[VMIN] = 1;

new_settings.c_cc[VTIME] = 0;

tcsetattr(0, TCSANOW, &new_settings);

}


void close_keyboard()

{

tcsetattr(0, TCSANOW, &initial_settings);

}


int _kbhit()

{

unsigned char ch;

int nread;


if (peek_character != -1) return 1;

new_settings.c_cc[VMIN]=0;

tcsetattr(0, TCSANOW, &new_settings);

nread = read(0,&ch,1);

new_settings.c_cc[VMIN]=1;

tcsetattr(0, TCSANOW, &new_settings);

if(nread == 1) 

{

peek_character = ch;

return 1;

}

return 0;

}


int _getch()

{

char ch;


if(peek_character != -1) 

{

ch = peek_character;

peek_character = -1;

return ch;

}

read(0,&ch,1);

return ch;

}


int _putch(int c) {

putchar(c);

fflush(stdout);

return c;

}


사용법


init_keyboard();

while (1) {

if (_kbhit()) {

int ch = _getch();

_putch(ch);

switch (ch) {

...

}

}

}

close_keyboard();



putch를 해주는 이유는 _getch호출 시 화면에 출력하지 않고 바로 input buffer에서 읽어오기 때문에 사용자에게 보여주기 위해 출력해줌.

'develop > linux' 카테고리의 다른 글

TTFB 체크 명령어  (0) 2016.02.16
GNU C, __attribute__  (0) 2014.10.14
NAT 종류별 설정  (0) 2014.02.17
Linux TCP/IP tunning  (0) 2014.01.08
Ubuntu에서 Oracle java 설치  (0) 2013.12.31

참조:http://forums.gentoo.org/viewtopic-t-826825-start-0.html


Full cone

#iptables -t nat -A POSTROUTING -o eth0 -p udp --sport {source port} -j SNAT --to-source {NAT public ip}

#iptables -t nat -A PREROUTING -i eth0 -p udp --dport {destination port} -j DNAT --to-destination {Client ip}


Symmetric

Masquerade 설정하면 됨



아래는 원문

I think the wikipedia page makes those distinctions a little clearer: 
http://en.wikipedia.org/wiki/Network_address_translation#Types_of_NAT 
I will be working on these definitions, which I take to be equivalent to yours. 

I disagree with Pedro Gonçalves's rules. In the Full Cone NAT rules he provides, he doesn't match ports, and so it seems as though all traffic coming in on eth0 would be forwarded through to 10.0.0.1 and all traffic leaving eth0 would be SNAT sourced from 192.168.2.170, regardless of port. The specifications specifically mention a particular port. 

I also expanded on Pedro Gonçalves's naming convention by adding interface names and host names: 
Public, 192.168.2.170, $EXTIF, router.network 
Private, 10.0.0.1, $INTIF, inner.network 
Port is $P in all cases (although it wouldn't have to be). 

The way I comprehend the question, a port number $P is given and must be a part of the rules. 

I don't think these rules are perfect; I'm the least sure about the restricted cones. Nevertheless I think it will move you in the right direction. 

Full cone NAT 
this covers outgoing traffic which should be rewritten to appear to come from router.network:$P. 1 ea. for UDP, TCP 

Code:
iptables -t nat POSTROUTING -o $EXTIF -p tcp --sport $P -j SNAT --to-source 192.168.2.170 
iptables -t nat POSTROUTING -o $EXTIF  -p udp --sport $P -j SNAT --to-source 92.168.2.170


now we need the reverse direction, incoming traffic on $P is forwarded to 10.0.0.1 

Code:
iptables -t nat PREROUTING -i $EXTIF -p tcp --dport $P -j DNAT --to-destination 10.0.0.1 
iptables -t nat PREROUTING -i $EXTIF -p udp --dport $P -j DNAT --to-destination 10.0.0.1



[Address] Restricted Cone Nat 
Here we reject incoming packets that aren't already established. First we need the rules above. Then we need an INPUT rule that will match incoming connections on $EXTIF:$P 
and accept only those which are connected already. Thus the connection must be instigated by inner.network. 

Code:

# previous rules 
iptables -t nat POSTROUTING -o $EXTIF -p tcp --sport $P -j SNAT --to-source 192.168.2.170 
iptables -t nat POSTROUTING -o $EXTIF  -p udp --sport $P -j SNAT --to-source 92.168.2.170 
iptables -t nat PREROUTING -i $EXTIF -p tcp --dport $P -j DNAT --to-destination 10.0.0.1 
iptables -t nat PREROUTING -i $EXTIF -p udp --dport $P -j DNAT --to-destination 10.0.0.1 
# FILTER rules to drop, rather than forward, new connections 
# we accept already established connections (These are only necessary if default policy is not ACCEPT) 
iptables -A INPUT -i $EXTIF -p tcp --dport $P -m state --state ESTABLISHED,RELATED -j ACCEPT 
iptables -A INPUT -i $EXTIF -p udp --dport $P -m state --state ESTABLISHED,RELATED -j ACCEPT 
# now rules to drop the packets otherwise (only necessary if default policy is not DROP) 
iptables -A INPUT -i $EXTIF -p tcp --dport $P -m state --state NEW -j DROP 
iptables -A INPUT -i $EXTIF -p udp --dport $P -m state --state NEW -j DROP 



Port Restricted Cone Nat 
This is the same as the above, except we also check the source port on the INPUT chain. 

Code:

# previous rules 
iptables -t nat POSTROUTING -o $EXTIF -p tcp --sport $P -j SNAT --to-source 192.168.2.170 
iptables -t nat POSTROUTING -o $EXTIF  -p udp --sport $P -j SNAT --to-source 92.168.2.170 
iptables -t nat PREROUTING -i $EXTIF -p tcp --dport $P -j DNAT --to-destination 10.0.0.1 
iptables -t nat PREROUTING -i $EXTIF -p udp --dport $P -j DNAT --to-destination 10.0.0.1 
# FILTER rules to drop, rather than forward, new connections 
# we accept already established connections (These are only necessary if default policy is not ACCEPT) 
iptables -A INPUT -i $EXTIF -p tcp --sport $P --dport $P -m state --state ESTABLISHED,RELATED -j ACCEPT 
iptables -A INPUT -i $EXTIF -p udp --sport $P --dport $P -m state --state ESTABLISHED,RELATED -j ACCEPT 
# now rules to drop the packets otherwise (only necessary if default policy is not DROP) 
iptables -A INPUT -i $EXTIF -p tcp --dport $P -m state --state NEW -j DROP 
iptables -A INPUT -i $EXTIF -p udp --dport $P -m state --state NEW -j DROP 



Symmetric NAT 
It seems that this could be called 'Full Nat' or 'Masquerading'. New connections are never forwarded through router.network to inner.network, but new connections are dynamically mapped to ports on $EXTIF. This is pretty complicated, but the iptables rule is very easy. 

Code:

# no other rules are required for this.  
iptables -t nat -I POSTROUTING -s 10.0.0.1 -o $EXTIF  -j MASQUERADE 


'develop > linux' 카테고리의 다른 글

GNU C, __attribute__  (0) 2014.10.14
Linux C에서 키보드 이벤트 받기(kbhit())  (0) 2014.02.28
Linux TCP/IP tunning  (0) 2014.01.08
Ubuntu에서 Oracle java 설치  (0) 2013.12.31
GCC에서 컴파일 시 문구 출력하기  (0) 2013.04.18

출처: http://www.lognormal.com/blog/2012/09/27/linux-tcpip-tuning/



We’re a performance company, and performance and scalability go hand in hand. Better scalability results in more consistent performance and at LogNormal, we like pushing our hardware as far as it will go.

Today’s post is about some of the infrastructure we use and how we tune it to handle a large number of requests.

We have separate components of our software stack to handle different tasks. In this post I’ll only cover the parts that make up our beacon collection component and how we tune it. Only a few of the tuning points are specific to this component.

The Stack

(side note… someone needs to start a Coffee Shop + Co-working Space called The Stack).

  • The beacon collector runs Linux at its base. We use a combination of Ubuntu 11.10 and 12.04, which for most purposes are the same. If you’re going with a new implementation though, I’d suggest 12.04 (or at least the 3.x kernels).

  • Slightly higher up is iptables to restrict inbound connections. This is mainly because we’re hosted on shared infrastructure and need to restrict internal communications only to hosts that we trust. iptables is the cheapest way to do this, but it brings in a few caveats that we address in the tuning section later.

  • We then have nginx set up to serve HTTP traffic on ports 80 and 443 and do some amount of filtering (more on this later)

  • Behind nginx is our custom node.js server that handles and processes beacons as they come in. It reads some configuration data from couchdb and then sends these processed beacons out into the ether. Nginx and node talk to each other over a unix domain socket.

That’s about all that’s relevant for this discussion, but at the heart of it, you’ll see that there are lots of file handles and sockets in use at any point of time.

A large part of this is due to the fact that nginx only uses HTTP/1.0 when it proxies requests to a back end server, and that means it opens a new connection on every request rather than using a persistent connection.

What should we tune?

In this post I’ll talk only about the first two parts of our stack. Linux and iptables.

Open files

Since we deal with a lot of file handles (each TCP socket requires a file handle), we need to keep our open file limit high. The current value can be seen using ulimit -a (look for open files). We set this value to 999999 and hope that we never need a million or more files open. In practice we never do.

We set this limit by putting a file into /etc/security/limits.d/ that contains the following two lines:

*	soft	nofile	999999
*	hard	nofile	999999

(side node: it took me 10 minutes trying to convince Markdown that those asterisks were to be printed as asterisks)

If you don’t do this, you’ll run out of open file handles and could see one or more parts of your stack die.

Ephemeral Ports

The second thing to do is to increase the number of Ephemeral Ports available to your application. By default this is all ports from 32768 to 61000. We change this to all ports from 18000 to 65535. Ports below 18000 are reserved for current and future use of the application itself. This may change in the future, but is sufficient for what we need right now, largely because of what we do next.

TIME_WAIT state

TCP connections go through various states during their lifetime. There’s the handshake that goes through multiple states, then the ESTABLISHED state, and then a whole bunch of states for either end to terminate the connection, and finally a TIME_WAIT state that lasts a really long time. If you’re interested in all the states, read through the netstat man page, but right now the only one we care about is the TIME_WAIT state, and we care about it mainly because it’s so long.

By default, a connection is supposed to stay in the TIME_WAIT state for twice the msl. Its purpose is to make sure any lost packets that arrive after a connection is closed do not confuse the TCP subsystem (the full details of this are beyond the scope of this article, but ask me if you’d like details). The default msl is 60 seconds, which puts the default TIME_WAIT timeout value at 2 minutes. Which means you’ll run out of available ports if you receive more than about 400 requests a second, or if we look back to how nginx does proxies, this actually translates to 200 requests per second. Not good for scaling.

We fixed this by setting the timeout value to 1 second.

I’ll let that sink in a bit. Essentially we reduced the timeout value by 99.16%. This is a huge reduction, and not to be taken lightly. Any documentation you read will recommend against it, but here’s why we did it.

Again, remember the point of the TIME_WAIT state is to avoid confusing the transport layer. The transport layer will get confused if it receives an out of order packet on a currently established socket, and send a reset packet in response. The key here is the term established socket. A socket is a tuple of 4 terms. The source and destination IPs and ports. Now for our purposes, our server IP is constant, so that leaves 3 variables.

Our port numbers are recycled, and we have 47535 of them. That leaves the other end of the connection.

In order for a collision to take place, we’d have to get a new connection from an existing client, AND that client would have to use the same port number that it used for the earlier connection, AND our server would have to assign the same port number to this connection as it did before. Given that we use persistent HTTP connections between clients and nginx, the probability of this happening is so low that we can ignore it. 1 second is a long enough TIME_WAITtimeout.

The two TCP tuning parameters were set using sysctl by putting a file into /etc/sysctl.d/ with the following:

net.ipv4.ip_local_port_range = 18000    65535
net.ipv4.netfilter.ip_conntrack_tcp_timeout_time_wait = 1

Connection Tracking

The next parameter we looked at was Connection Tracking. This is a side effect of using iptables. Since iptablesneeds to allow two-way communication between established HTTP and ssh connections, it needs to keep track of which connections are established, and it puts these into a connection tracking table. This table grows. And grows. And grows.

You can see the current size of this table using sysctl net.netfilter.nf_conntrack_count and its limit usingsysctl net.nf_conntrack_max. If count crosses max, your linux system will stop accepting new TCP connections and you’ll never know about this. The only indication that this has happened is a single line hidden somewhere in/var/log/syslog saying that you’re out of connection tracking entries. One line, once, when it first happens.

A better indication is if count is always very close to max. You might think, “Hey, we’ve set max exactly right.”, but you’d be wrong.

What you need to do (or at least that’s what you first think) is to increase max.

Keep in mind though, that the larger this value, the more RAM the kernel will use to keep track of these entries. RAM that could be used by your application.

We started down this path, increasing net.nf_conntrack_max, but soon we were just pushing it up every day. Connections that were getting in there were never getting out.

nf_conntrack_tcp_timeout_established

It turns out that there’s another timeout value you need to be concerned with. The established connection timeout. Technically this should only apply to connections that are in the ESTABLISHED state, and a connection should get out of this state when a FIN packet goes through in either direction. This doesn’t appear to happen and I’m not entirely sure why.

So how long do connections stay in this table then? The default value for nf_conntrack_tcp_timeout_established is 432000 seconds. I’ll wait for you to do the long division…

Fun times.

I changed the timeout value to 10 minutes (600 seconds) and in a few days time I noticed conntrack_count go down steadily until it sat at a very manageable level of a few thousand.

We did this by adding another line to the sysctl file:

net.netfilter.nf_conntrack_tcp_timeout_established=600

Speed bump

At this point we were in a pretty good state. Our beacon collectors ran for months (not counting scheduled reboots) without a problem, until a couple of days ago, when one of them just stopped responding to any kind of network requests. No ping responses, no ACK packets to a SYN, nothing. All established ssh and HTTP connections terminated and the box was doing nothing. I still had console access, and couldn’t tell what was wrong. The system was using less than 1% CPU and less than 10% of RAM. All processes that were supposed to be running were running, but nothing was coming in or going out.

I looked through syslog, and found one obscure message repeated several times.

IPv4: dst cache overflow

Well, there were other messages, but this was the one that mattered.

I did a bit of searching online, and found something about an rt_cache leak in 2.6.18. We’re on 3.5.2, so it shouldn’t have been a problem, but I investigated anyway.

The details of the post above related to 2.6, and 3.5 was different, with no ip_dst_cache entry in /proc/slabinfo so I started searching for its equivalent on 3.5 when I came across Vincent Bernat's post on the IPv4 route cache. This is an excellent resource to understand the route cache on linux, and that’s where I found out about the lnstatcommand. This is something that needs to be added to any monitoring and stats gathering scripts that you run.Further reading suggests that the dst cache gc routines are complicated, and a bug anywhere could result in a leak, one which could take several weeks to become apparent.

From what I can tell, there doesn’t appear to be an rt_cache leak. The number of cache entries increases and decreases with traffic, but I’ll keep monitoring it to see if that changes over time.

Other things to tune

There are a few other things you might want to tune, but they’re becoming less of an issue as base system configs evolve.

TCP Window Sizes

This is related to TCP Slow Start, and I’d love to go into the details, but our friends Sajal and Aaron over at CDN Planet have already done an awesome job explaining how to tune TCP initcwnd for optimum performance.

This is not an issue for us because the 3.5 kernel’s default window size is already set to 10.

Window size after idle

Related to the above is the sysctl setting net.ipv4.tcp_slow_start_after_idle. This tells the system whether it should start at the default window size only for new TCP connections or also for existing TCP connections that have been idle for too long (on 3.5, too long is 1 second, but see net.sctp.rto_initial for its current value on your system). If you’re using persistent HTTP connections, you’re likely to end up in this state, so setnet.ipv4.tcp_slow_start_after_idle=0 (just put it into the sysctl config file mentioned above).

Endgame

After changing all these settings, a single quad core vm (though using only one core) with 1Gig of RAM has been able to handle all the load that’s been thrown at it. We never run out of open file handles, never run out of ports, never run out of connection tracking entries and never run out of RAM.

We have several weeks before another one of our beacon collectors runs into the dst cache issue, and I’ll be ready with the numbers when that happens.

Thanks for reading, and let us know how these settings work out for you if you try them out. If you’d like to measure the real user impact of your changes, have a look at our Real User Measurement tool at LogNormal.

Update 2012-09-28: There are some great comments on hacker news with much more information.

apt-get으로 jre를 설치해야 하는데 설치 목록엔 있지만 설치할 수가 없는경우.

oracle사이트에서 jre를 적당한 폴더에 다운 받는다.

(windows에서 받은 후 ftp로 업로드 해도 됨)


1. 압축파일이면 그냥 압축만 풀면 되고, bin파일이면 권한 설정 후 실행.

chmod 744 jre-6u34-linux-x64.bin

./jre-6u34-linux-x64.bin


2. jvm폴더 생성 및 jre폴더 이동

mkdir /usr/lib/jvm

mv jre-6u34-linux-x64.bin /usr/lib/jvm


3. 자바 실행파일 설정

update-alternatives --install /usr/bin/java java /usr/lib/jvm/jre1.6.0_34/bin/java 0


그 외 기타 설정은 아래 참조

http://www.liberiangeek.net/2012/04/install-oracle-java-runtime-jre-7-in-ubuntu-12-04-precise-pangolin/

'develop > linux' 카테고리의 다른 글

NAT 종류별 설정  (0) 2014.02.17
Linux TCP/IP tunning  (0) 2014.01.08
GCC에서 컴파일 시 문구 출력하기  (0) 2013.04.18
리눅스 키보드 이벤트 받아서 키 입력받기(개행포함)  (0) 2013.02.08
Raw 소켓  (0) 2012.12.28

윈도우에서 사용법은

http://machari.tistory.com/entry/gcc%EC%97%90%EC%84%9C-pragma-warning-%EC%B2%98%EB%9F%BC-compile%EC%8B%9C-%EC%82%AC%EC%9A%A9%EC%9E%90-%EC%A0%95%EC%9D%98-%EA%B2%BD%EA%B3%A0-%EB%AC%B8%EA%B5%AC-%ED%91%9C%EC%8B%9C%ED%95%98%EA%B8%B0



컴파일 시 아직 코딩 못한 부분을 상기하고 싶다거나 할 때 사용

GCC 4.x이상 버전에서 테스트함.


#pragma message("msg")


결과

test.c:3: note: #pragma message: msg


해당 소스 파일명과 줄번호까지 나온다.





쓰고보니 사용법이 똑같은거 같네 -_-;;


리눅스용 참조

http://gcc.gnu.org/onlinedocs/gcc-4.4.7/gcc/Diagnostic-Pragmas.html#Diagnostic-Pragmas

standard input file descriptor를 이용


int STDIN = fileno(stdin);

int maxfd = (socket > STDIN)? socket: STDIN;

...

while (...) {

FD_SET(STDIN, &rdSet);

if (select(maxfd + 1, &rdSet, NULL, NULL, NULL) == -1) {printf("select()\n"); }

...

if (FD_ISSET(STDIN, &rdSet)) {

if (read(STDIN, cmd, 200) <= 0) continue ;

ParseCmd(rawSocket, cmd);

}

}

...

}


'develop > linux' 카테고리의 다른 글

Ubuntu에서 Oracle java 설치  (0) 2013.12.31
GCC에서 컴파일 시 문구 출력하기  (0) 2013.04.18
Raw 소켓  (0) 2012.12.28
find 명령어로 특정 시간내의 파일 찾기  (0) 2012.11.16
PostgreSQL Streaming Replication  (0) 2012.08.22

+ Recent posts